如何在C+中使用智能指针+;在下面的示例中提供帮助 我正在阅读C++中的智能指针,并看到这个例子给出了如果指针使用普通指针,智能指针如何处理“悬吊指针”问题。我知道AutoPPTR是由C++ 2011表示的,但它仍然有UNIQUYYPTR或一些类似的。

如何在C+中使用智能指针+;在下面的示例中提供帮助 我正在阅读C++中的智能指针,并看到这个例子给出了如果指针使用普通指针,智能指针如何处理“悬吊指针”问题。我知道AutoPPTR是由C++ 2011表示的,但它仍然有UNIQUYYPTR或一些类似的。,c++,smart-pointers,C++,Smart Pointers,悬挂的指针。常规指针的一个常见陷阱是悬挂指针:指向已删除对象的指针。以下代码(例如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

悬挂的指针。常规指针的一个常见陷阱是悬挂指针:指向已删除对象的指针。以下代码(例如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!
使用auto_ptr,可以通过在复制时将其指针设置为NULL来解决此问题(复制构造函数的实现如下所示):

模板
auto_ptr&auto_ptr::operator=(auto_ptr&rhs)
{
如果(此!=&rhs){
删除ptr;
ptr=rhs.ptr;
rhs.ptr=NULL;
}
归还*这个;
}
现在,如果我们使用auto_ptr获得相同的代码,如下所示:

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;
}
auto_ptr<MyClass> p(new MyClass);
auto_ptr<MyClass> q = p;
delete p;
p->DoSomething();   
p = NULL;           
q->DoSomething();   
auto_ptr p(新MyClass);
自动_ptr q=p;
删除p;
p->DoSomething();
p=零;
q->DoSomething();
我在aqbove复制构造函数中得到了逻辑,但是如何使rhs.ptr=NULL有帮助呢。我的意思是,如果稍后取消引用这个指针(在上面的代码示例中为q),它将崩溃,因为它被智能指针复制构造函数设置为NULL


如果它是一个普通的指针,我们会去引用一个悬挂的指针,那么会发生什么呢?可能是一些未定义的行为。但是,如何使用auto_ptr help和
共享_ptr
您永远不会手动删除它正在管理的内存;当对它的最后一次引用超出范围时,它会自动删除。这使得悬空指针几乎不可能出现,除非您手动重置它。

使用
auto\u ptr
可以专门测试
NULL
,以确保指针实际指向某个对象。通过复制构造函数和
运算符=
方法复制指针值的所有权可确保如果指针的所有权被“移动”,指针实际上将为
NULL
。最后,当
auto_ptr
超出范围时,如果内部指针未设置为
NULL
(即所有权尚未放弃),它将释放其拥有的指针的内存


另一方面,对于裸指针,您无法确定指针是否悬空,或者谁“拥有”指针,除非您注意确保删除后将指针设置为
NULL
,等等。。。但手动执行此操作并非异常安全。另一方面,
auto\u ptr
的接口使指针的“所有权”明确,并使动态内存分配异常安全。

首先,该示例是错误的,因为它在删除p之后调用了
p->DoSomething()
。其次,在使用auto_ptr时,您不会直接调用delete,这由auto_ptr的析构函数负责。第三,auto_ptr的要点是它不允许指针的多个副本,因此不可能存在悬空指针。空指针异常比悬空指针更可取,因为行为已定义。

首先,它会阻止代码编译。语句
delete p
无效,因为您无法删除
auto_ptr
。当您在智能指针中存储地址时,您不应再对其调用
delete
;任何对
delete
的调用都会立即导致对代码进行更仔细的检查-它看起来是错误的


删除
delete
语句后,运行时错误会更快出现。使用
p
初始化
q
后,
p
包含一个空指针。因此,
p->DoSomething()
在空指针上调用该方法,这将比在原始代码中调用旧的无效指针上的方法更快地导致崩溃。(对空指针调用方法会导致未定义的行为。典型的结果是崩溃,如访问冲突或分段错误。对无效指针调用方法也未定义,但通常会导致更细微的错误,如丢弃的数据或不正确的计算,而不是崩溃。)

如果未先检查就取消引用智能指针,则智能指针不一定会保护您;它们给你的是一种保证,你可以在取消引用之前检查它们是否有效

悬空指针的问题在于它没有指向任何有效的对象,但无法判断:

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
有了智能指针,你永远不会有那种情况;指针有效,或者可以在取消引用之前判断它无效:

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
auto_ptr p(新事物);
自动_ptr q=p;
如果(p)p->DoSomething();//好的:检查p,什么也不做
如果(q)q->DoSomething();//OK:检查q,调用函数
p、 重置();//无所事事
如果(p)p->DoSomething();//好的:检查p,什么也不做
如果(q)q->DoSomething();//OK:检查q,调用函数
q、 重置();//删除对象
如果(p)p->DoSomething();//好的:检查p,什么也不做
如果(q)q->DoSomething();//OK:检查q,什么都不做

在任何东西悬空之前,您的第一个示例已经是未定义的行为。首先试着理解常规指针。@pmr-请你写一行解释这是怎么回事。你可以创建一个对象。用两个不同的指针指向它<代码>删除它,然后调用一个方法。相关问题我不知道你是否错了,但最初的例子是不完整的。最初的一个通过悬空指针访问,
std::auto_ptr
的示例代码不是合法的实现(如果是,则在自赋值时会失败),最后一个示例在auto_ptr上执行
delete
,甚至不应该编译。