C++ 编程/运算符/指针/智能指针
外观
此页面可能需要更新以反映当前知识。 由于 C++11 中 auto_ptr 已被弃用,不再应该使用。 应该使用新的智能指针来代替 auto_ptr:unique_ptr、weak_ptr 和 shared_ptr。 现在 unique_ptr 应该作为 auto_ptr 的替代首选。 你可以 帮助更新它,讨论进度,或 请求帮助. |
使用原始指针存储分配的数据,然后在析构函数中清理它们,通常被认为是一个非常糟糕的想法,因为它容易出错。 即使将分配的数据暂时存储在原始指针中,然后在完成操作后删除它,也应该出于这个原因避免这样做。 例如,如果您的代码抛出异常,正确捕获异常并删除所有分配的对象可能很麻烦。
智能指针可以通过使用编译器和语言语义来确保指针内容在指针本身超出范围时自动释放,从而缓解这种头痛。
#include <memory>
class A
{
public:
virtual ~A() {}
virtual char val() = 0;
};
class B : public A
{
public:
virtual char val() { return 'B'; }
};
A* get_a_new_b()
{
return new B();
}
bool some_func()
{
bool rval = true;
std::auto_ptr<A> a( get_a_new_b() );
try {
std::cout << a->val();
} catch(...) {
if( !a.get() ) {
throw "Memory allocation failure!";
}
rval = false;
}
return rval;
}
auto_ptr 具有严格所有权的语义,这意味着 auto_ptr 实例是负责对象生命周期的唯一实体。 如果复制一个 auto_ptr,源将丢失对该引用的引用。 例如
#include <iostream>
#include <memory>
using namespace std;
int main(int argc, char **arv)
{
int *i = new int;
auto_ptr<int> x(i);
auto_ptr<int> y;
y = x;
cout << x.get() << endl;
cout << y.get() << endl;
}
此代码将打印第一个 auto_ptr 对象的 NULL 地址,以及第二个的某个非 NULL 地址,这表明源对象在赋值期间(=)丢失了对该引用的引用。 示例中的原始指针 i
不应该被删除,因为它将由拥有该引用的 auto_ptr 删除。 事实上,new int
可以直接传递到 x 中,从而消除了对 i
的需要。
请注意,由 auto_ptr 指向的对象使用 operator delete
销毁;这意味着您应该只对使用 operator new
获得的指针使用 auto_ptr。 这不包括由 malloc()
、calloc()
或 realloc()
和 operator new[]
返回的指针。