2015-06-23 98 views
0

我正在使用VS2012。
我將代碼從原始指針移植到unique_ptr並面臨問題。
在這裏,我試圖模擬場景:具有虛擬和非虛擬功能的unique_ptr :: get()函數

class xyz{ 
    public: 
    virtual int getm(); 
    int get();  
    static std::unique_ptr<xyz> returnbase(); 
}; 

class abc:public xyz 
{ 
public: 
    int getm() {return 0;} 
}; 

std::unique_ptr<xyz> xyz::returnbase() 
{ 
    std::unique_ptr<xyz> u_Swift(nullptr); 
    u_Swift = std::unique_ptr<xyz>(dynamic_cast<xyz*>(new abc())); 
    return u_Swift; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    xyz* x1 = xyz::returnbase().get(); 
    x1->get(); 
    x1->getm(); 
    return 0; 
} 

我得到一個崩潰「訪問衝突」而調用虛函數。
我很驚訝,爲什麼這是崩潰的虛擬功能?

通過觀察我可以看到分配後虛擬指針已損壞。但爲什麼這是腐敗的,我很好奇。

+0

格式化你的代碼。 –

+0

爲什麼你寫這樣一個非常冗長的代碼?例如'returnbase()'應該由一個語句組成:'return std :: unique_ptr (dynamic_cast (new xyz()));' –

+4

將'new xyz()'鑄造成'xyz *'?它已經是'xyz *'了。 – Wintermute

回答

6

您的x1是一個懸掛指針,因爲擁有其初始指針的臨時唯一指針在main的第一個語句末尾被銷燬,因此指針被破壞。

xyz* x1 = xyz::returnbase().get(); 
//  ^^^^^^^^^^^^^^^^^  ^^ 
//   temporary object  ^-- destroyed here 

要保留的對象,你需要使它非暫時性的,就像這樣:

int main() 
{ 
    std::unique_ptr<xyz> thing = xyz::returnbase(); 
    xyz * x1 = thing.get(); 

    // ... use x1 and *x1 ... 

} // thing goes out of scope and *thing is destroyed