发生了什么
当您编写T t; 时,您正在创建一个具有自动存储持续时间的T 类型的对象。超出范围时会自动清理。
当您编写new T() 时,您正在创建一个具有动态存储持续时间的T 类型的对象。它不会自动清理。
您需要将指向它的指针传递给delete 以便清理它:
但是,您的第二个示例更糟糕:您正在取消引用指针,并制作对象的副本。这样一来,您将丢失指向使用 new 创建的对象的指针,因此即使您愿意,也永远无法删除它!
你应该做什么
您应该更喜欢自动存储期限。需要一个新对象,只需写:
A a; // a new object of type A
B b; // a new object of type B
如果您确实需要动态存储持续时间,请将指向分配对象的指针存储在自动存储持续时间对象中,该对象会自动删除它。
template <typename T>
class automatic_pointer {
public:
automatic_pointer(T* pointer) : pointer(pointer) {}
// destructor: gets called upon cleanup
// in this case, we want to use delete
~automatic_pointer() { delete pointer; }
// emulate pointers!
// with this we can write *p
T& operator*() const { return *pointer; }
// and with this we can write p->f()
T* operator->() const { return pointer; }
private:
T* pointer;
// for this example, I'll just forbid copies
// a smarter class could deal with this some other way
automatic_pointer(automatic_pointer const&);
automatic_pointer& operator=(automatic_pointer const&);
};
automatic_pointer<A> a(new A()); // acts like a pointer, but deletes automatically
automatic_pointer<B> b(new B()); // acts like a pointer, but deletes automatically
这是一个常见的习惯用法,名称不是很具描述性的 RAII(资源获取即初始化)。当您获得需要清理的资源时,将其粘贴在自动存储期限的对象中,因此您无需担心清理它。这适用于任何资源,无论是内存、打开的文件、网络连接还是您喜欢的任何资源。
automatic_pointer 这个东西已经以各种形式存在,我只是提供了它来举例。标准库中有一个非常相似的类,称为std::unique_ptr。
还有一个名为 auto_ptr 的旧版本(C++11 之前的版本),但现在已被弃用,因为它具有奇怪的复制行为。
还有一些更聪明的例子,比如std::shared_ptr,它允许多个指针指向同一个对象,并且只有在最后一个指针被销毁时才清理它。