2013-02-21 69 views
0

我已经从运算符T *()返回指针对象类型,并通过智能指针调用删除操作符,并尝试调用成员函数,并且我没有任何运行时错误。这怎么可能?或者我的理解是错误的?请建议。删除智能指针,但仍可以访问指针?

#include <iostream> 

using namespace std; 

template <typename T> 
class sPtr 
{ 
    private: 
     T * pointee__; 
    public: 

     operator T *() { 
       cout <<"Inside T*() "<<endl; 
       return pointee__; 
     }; 
    explicit sPtr (T * t) 
    { 

     pointee__ = t; 
    }; 
    T * operator->() { 
     return pointee__; 
    } 
}; 

class JTest 
{ 
private: 
     int x; 
public: 
    JTest (int l=100) { x=l; }; 
    void display(); 
}; 

void JTest::display() 
{ 
    cout <<"Display API x is "<<x<<endl; 
} 

void JFunc (JTest * tmp) 
{ 
    cout <<" JFunc"<<endl; 
    tmp->display(); 
    cout <<"Invoking JTest -> display "<<endl; 
} 


int main (int argc, char ** argv) 
{ 
sPtr <JTest> t(new JTest); 
t->display(); 
delete t; // Invokes operator T*() , and it is dangerous!!!.. 
t->display (); 

} 

OUTPUT:

Display API x is 100 
Inside T*() 
Display API x is 100 
+8

[停止偷酒店房间钥匙!](http://stackoverflow.com/a/6445794/46642) – 2013-02-21 14:15:39

+0

如果你的问题是:“为什么每次我调用UB时都不会UB崩溃”,那么答案是:“因为它的UB” – PlasmaHH 2013-02-21 14:16:53

+0

你正在做一些你不允许的事情。询问期望什么没有意义。 – 2013-02-21 14:22:17

回答

3

删除吨标志着存储器指向吨为未使用,但保留存储在吨完整地址。当您尝试使用存储在t中的对象时,C++不会检查它是否已被删除,因此当您拥有的对象经常会崩溃时,如果删除的对象所使用的内存尚未被系统覆盖,它可能偶尔会工作。

简而言之:有时这会起作用,往往会崩溃,而且这总是一个坏主意。

如果您想保护自己,请在删除它之后将其设置为NULL。

+2

最好保护自己不受自己干扰的方法是不要让任何已删除的指针暴露出来,即,使delete的所有用法都与私有数据成员一起使用,并且始终在析构函数内部。或者更好的是,忘掉“删除”并遵循[零规则](http://flamingdangerzone.com/cxx11/2012/08/15/rule-of-zero.html)。 (IOW,如果你为每个顾客提供一个礼宾服务,总是为他们打开房间,人们不能偷酒店房间钥匙) – 2013-02-21 14:26:06

+0

感谢Martinho。 YOu帮助了解信息,而不是......)。 – Whoami 2013-02-21 16:36:41