2013-02-21 113 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