2013-10-12 28 views
0

我得到這個類(從我剛纔的問題,我只是改變了一些東西):智能指針與類,它指向哪裏?

class Tree{ 
private: 
    shared_ptr<Tree> Left; 
    shared_ptr<Tree> Right; 
    int Info; 
public: 
    Tree() :Info(0) ,Left(nullptr), Right(nullptr) {}; 
    Tree(int num) : Info(num), Left(nullptr) , Right(nullptr){}; 
    Tree& operator=(const Tree &src); 
    void SetLeft(int num){Left.reset(new Tree(num));}; 
    void SetRight(int num){Right.reset(new Tree(num));}; 
    void SetInfo(int num){Info = num;}; 
    Tree GetLeft(){return *Left;}; 
    Tree GetRight(){return *Right;}; 
    int GetInfo(){return Info;}; 
}; 
Tree& Tree::operator=(const Tree &src){ 
    Left = src.Left; 
    Right = src.Right; 
    Info = src.Info; 
    return *this; 
} 

該類創建樹有2個葉LeftRight(其中有分類很好,但在shared_ptr的) 。

所以我這樣做:

Tree tr(75); 
tr.SetLeft(5); 
tr.GetLeft().SetLeft(7); 
tr.SetRight(3); 
tr.GetRight().SetRight(1); 

,當我嘗試來清點了左>左或右鍵 - >右鍵Info(這是每棵樹的價值):

cout << tr.GetRight().GetRight().GetInfo(); 

我得到一個奇怪的錯誤,關於智能指針(關於reset函數),編譯器在這裏創建了一個斷點:

void _Reset(const _Ptr_base<_Ty2>& _Other) 
    { // release resource and take ownership of _Other._Ptr 
    _Reset(_Other._Ptr, _Other._Rep); 
    } 

我做錯了什麼? 謝謝! :)


編輯:

我試圖檢查也許是因爲nullptr和我編譯如下:

shared_ptr<int> i; 
int ib=6; 
i=nullptr; 
i.reset(&ib); 
cout << *i; 

程序編譯後,我不知從哪兒"Debug Assertion Failed!"得到一個錯誤。 我不認爲它連接到我的問題,但是造成了什麼?

回答

2

我不知道這是否是特定錯誤的原因,但是這會咬你最終:

Tree GetLeft(){return *Left;}; 

返回複製左。你想返回一個參考:

Tree& GetLeft(){return *Left;} 

(也}通知後沒有分號)

+0

謝謝修復! –

1

此代碼:

class Tree{ 
... 
    Tree GetLeft(){return *Left;}; 
    Tree GetRight(){return *Right;}; 
... 
}; 

份左右的樹木分別在返回創建。 這意味着下面的語句:

tr.GetLeft().SetLeft(7); 
tr.GetRight().SetRight(1); 

設置左,臨時副本分別爲「TR」樹的左右孩子的,右側的樹木。 您可以使用以下聲明輕鬆地進行測試(假設在當前上下文中允許訪問左側和右側),這將會失敗,因爲將給定子樹的臨時副本的地址與原來subreee:

assert(&tr.GetLeft() == &tr.Left.get()); 
assert(&tr.GetRight() == &tr.Right.get()); 

正確的版本應該是:

class Tree{ 
... 
    Tree& GetLeft(){return *Left;} 
    Tree& GetRight(){return *Right;} 
... 
}; 

如要返回而不是複製一個參考實際子樹對象。 使用這個版本,你的代碼應該像你期望的那樣運行,並且上面的斷言不會失敗。