重要的
请记住,它std::auto_ptr
有很多缺点std::unique_ptr
,如果您的编译器提供它,您通常应该使用它。(如果没有,请更新您的编译器!:))
现在回到你的问题...
使用这个 auto_ptr 有什么意义?它在超出范围时调用类析构函数作为普通类初始化变量(a)
确切地。的原因auto_ptr
是强制执行严格的所有权语义 - 以便在销毁指针本身时正确销毁对象。
我不能将此指针传递给具有类指针 (func) 的函数
你可以,你需要使用get()
来查找原始指针。将get()
指针传递给函数调用时使用意味着该函数不会获得对象的所有权(auto_ptr
仍然拥有它并期望它在函数返回后仍然有效)。
或者,您可以使用release()
指针来获取原始指针并指示auto_ptr
不再负责对象的所有权。
我不能将指针 auto_ptr 用于 A[] 或 char[] 因为 auto_ptr 调用 delete 而不是 delete[]
是的,这是个问题。auto_ptr
这也是自unique_ptr
推出以来不再使用的原因之一。它做同样的事情,但更安全(=更容易)使用和更通用。
唯一的想法是我不必写delete,但是当我超出范围时它会被破坏,那么指针的意义是什么。
这样您就不会忘记它:-) 或者您可以使用auto_ptr
(或更好地unique_ptr
作为类对象中的成员)。
但是告诉我使用 auto_ptr 而不是普通指针是什么意思?
长话短说:许多指针可以指向单个对象。存在各种智能指针以使用类型系统来记录哪个指针拥有对象(= 负责释放它)。
旁注
如果您有一个(可能)拥有另一个对象实例的类,您只需编写:
class X {
// ...
X() : ptr(new Type()) {}
X(Type ptr) : ptr(ptr) {}
// ...
void setPtr(Type ptr2) { ptr.reset(ptr); }
// ...
std::unique_ptr<Type> ptr;
};
如果ptr
设置了,那么例如unique_ptr
的析构函数将负责删除对象(如果有的话)。在该setPtr
方法中,该reset()
函数将删除旧实例(如果有的话)并将成员设置为提供的新实例(或 null - 没关系)。
现在比较另一种情况:
class X {
// ...
X() : ptr(new Type()) {}
X(Type ptr) : ptr(ptr) {}
// ...
void setPtr(Type ptr2) {delete ptr; ptr = ptr2;}
// ...
Type* ptr;
};
同样的行为?不!因为现在,为了拥有安全的 C++ 代码,您还需要编写一个析构函数来ptr
在X
被销毁时删除。
现在没事了?不!因为由于您有一个公共析构函数,您需要汇总(或阻止)您自己的复制构造函数和赋值运算符,因为否则您最终可能会得到两个指向同一个 Type 对象的 X 实例——并且两个实例都会认为他们拥有这个实例,并且有时都会尝试删除它。繁荣,访问违规。
Unique_ptr 不允许您隐式复制 X 对象以及对 的强引用ptr
,因为 unique_ptr 是不可复制的(它认为它是对象的唯一 unique_ptr,因此它是唯一负责删除它的智能指针实例- 但如果原始的、非拥有的指针指向它也没关系,只要他们不尝试删除他们不拥有的东西!)。
这不是全部—— unique_ptr 不能被复制,但它有一个移动构造函数和一个移动赋值运算符为你准备好了!因此,您可以安全地从函数等中返回它。
这就是智能指针的类型安全如何转化为编写更安全的代码。
黄金法则:尽量避免编写“删除”(除非您正在编写自己的容器或智能指针)。:)