gol*_*ean 2 c++ smart-pointers
我正在阅读C++中的智能指针,并看到这个例子给出了如果使用普通指针,智能指针如何处理"悬空指针"问题.PS我知道auto_ptr被C++ 2011弃用了,但它仍然有unique_ptr或者它的一些等价物.
晃来晃去的指针.常规指针的常见缺陷是悬空指针:指向已删除对象的指针.以下代码(例如用于jsut)说明了这种情况:
MyClass* p(new MyClass);//Assume we have a MyClass definition available
MyClass* q = p;
delete p;
p->DoSomething();
p = NULL; // p is not dangling anymore
q->DoSomething(); // Don't.. q is still dangling!
Run Code Online (Sandbox Code Playgroud)
使用auto_ptr,这可以通过在复制时将其指针设置为NULL来解决(复制构造函数实现如下):
template <class T>
auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<T>& rhs)
{
if (this != &rhs) {
delete ptr;
ptr = rhs.ptr;
rhs.ptr = NULL;
}
return *this;
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我们使用auto_ptr具有相同的代码,如下所示:
auto_ptr<MyClass> p(new MyClass);
auto_ptr<MyClass> q = p;
delete p;
p->DoSomething();
p = NULL;
q->DoSomething();
Run Code Online (Sandbox Code Playgroud)
我得到了aqbove复制构造函数中的逻辑,但是如何使rhs.ptr = NULL有帮助.我的意思是如果稍后一个解引用此指针(上面的代码示例中的q),它将崩溃,因为它由智能指针复制构造函数使其为NULL.
如果它是一个正常的指针,我们会取消引用一个悬空指针,那会发生什么?一些未定义的行为可能.但是如何使用auto_ptr帮助
智能指针不一定会保护你,如果你取消它们而不先检查它们; 他们给你的是保证你可以在解除引用之前检查它们是否有效.
悬挂指针的问题在于它没有指向任何有效的东西,但没有办法告诉:
Thing * p = new Thing;
Thing * q = p;
if (p) p->DoSomething(); // OK: checks p, calls function
if (q) q->DoSomething(); // OK: checks q, calls function
delete p;
p = nullptr;
if (p) p->DoSomething(); // OK: checks p, does nothing
if (q) q->DoSomething(); // BOOM! Undefined behaviour
Run Code Online (Sandbox Code Playgroud)
有了智能指针,你永远不会有这种情况; 指针有效,或者在解除引用之前可以告诉它无效:
auto_ptr<Thing> p(new Thing);
auto_ptr<Thing> q = p;
if (p) p->DoSomething(); // OK: checks p, does nothing
if (q) q->DoSomething(); // OK: checks q, calls function
p.reset(); // does nothing
if (p) p->DoSomething(); // OK: checks p, does nothing
if (q) q->DoSomething(); // OK: checks q, calls function
q.reset(); // deletes the object
if (p) p->DoSomething(); // OK: checks p, does nothing
if (q) q->DoSomething(); // OK: checks q, does nothing
Run Code Online (Sandbox Code Playgroud)