2010-04-04 44 views
4

我有一個類模型:從CardStack爲什麼這些shared_ptrs不指向同一個容器?

class Model 
{ 
    ... 

    boost::shared_ptr<Deck> _deck; 
    boost::shared_ptr<CardStack> _stack[22]; 
}; 

Deck繼承。

我試圖去讓_stack[0]指向同一件事,_deck點:

{ 
    _deck = boost::shared_ptr<Deck>(new Deck()); 
    _stack[0] = _deck; 
} 

似乎正在取得分配給_stack[0]_deck導致的_deck副本。 (我知道這是因爲對_stack[0]的修改不會導致對_deck的修改。)我怎樣才能讓他們指向相同的東西?

好的 - 沒有複製構造函數被調用。我已經通過實施驗證了這一點,並看到它是否被調用 - 事實並非如此。

然而 - 我有上CardStack對象進行動作的功能:

void TransferSingleCard(CardStack & src, CardStack & dst, Face f) 
{ 
    if(!src._cards.empty()) 
    { 
     src._cards.back().SetFace(f); 
     dst.PushCard(src._cards.back()); 
     src._cards.pop_back(); 
    } 

} 

現在 - 當我打電話:我得到這個輸出(在那裏的std ::在CardStack COUT將

{ 
    TransferSingleCard(*_stack[DECK], _someotherplace, FACEDOWN); 
    std::cout << *_stack[DECK]; 
    std::cout << *_deck; 
} 

打印出該堆棧的大小):

Num(103) TOP 
Num(104) TOP 

...所以我已經總結(不正確?)_stack[DECK]指向不同的東西。

甲板

class Deck : public CardStack 
{ 
public: 
    Deck(int numsuits=2, StackIndex index = NO_SUCH_STACK); 
    Deck::Deck(const Deck & d); 
    int DealsLeft() const; 
    void RecalcDealsLeft(); 
private: 
    int _dealsleft; 
}; 
+0

這應該工作。你得到了什麼錯誤,或者你如何知道正在製作副本。 – 2010-04-04 16:52:25

+0

@ Space_C0wb0y - 我知道這是一個副本,因爲我通過將'Card'對象拉出來修改'_stack [0]'(它基本上是'Card'對象的容器)。然後我查詢它們 - '_stack [0]'的大小已經縮小了,但'_deck'的大小仍然和pull之前一樣。 – BeeBand 2010-04-04 16:55:08

+0

你有沒有嘗試使兩個'shared_ptr'屬於同一類型?你能說明你做了什麼修改嗎?另外,嘗試實現一個複製構造函數,看看它是否被調用(它不應該)。你可以顯示'Deck'和'CardStack'類嗎? – 2010-04-04 16:57:37

回答

1

這個例子 - 來自於@尼爾的答案,試圖模仿你說的話。你能否檢查它是否按預期工作(A和B具有相同的計數)在你的系統上。

然後,我們可以嘗試修改此代碼或您的代碼,直到它們匹配。

#include <boost/shared_ptr.hpp> 
#include <iostream> 

class A { 
    public: 
    virtual ~A() 
    { 
     std::cerr << "Delete A" << std::endl; 
    } 
    int _count; 
    void decrement() 
    { 
     _count --; 
    } 
}; 
class B : public A { 
    public: 
    virtual ~B() 
    { 
     std::cerr << "Delete B" << std::endl; 
    } 
}; 

int main() 
{ 
    boost::shared_ptr<B> b(new B); 
    b->_count = 104; 
    boost::shared_ptr<A> a; 
    a = b; 

    a->decrement(); 

    std::cerr << "A:" << a->_count << std::endl; 
    std::cerr << "B:" << b->_count << std::endl; 
    return 0; 
} 

編輯:

因此,從評論,我們知道原來的指針是正確的,所以現在我們需要跟蹤。

或者:

  1. 日誌指針時看到他們改變。
  2. 在調試器中使用觀察點來查看指針何時更改。
  3. 使用第三個共享指針來查看哪個指針被更改。
  4. 引入一個同時更改兩個指針的函數。
+0

那麼,我回到基礎知識,你的代碼證明他們確實*開始*指向相同的東西。 'TransferSingleCard()'甚至可以工作 - 大小是一樣的。然而,更進一步,'TransferSingleCard()'給了我每個指針的不同結果。 – BeeBand 2010-04-04 19:39:49

+0

我想這意味着其中一個指針正在發生變化 - 我建議您在每次打印大小時記錄指針地址,並查看它們何時被更改。 – 2010-04-04 19:53:33

+0

是的,你是對的。 '_deck'指針通過'boost :: shared_ptr :: reset()'被重置爲其他東西。我想,我曾以爲,'復位()'不會改變_deck'的'地址(不知道爲什麼回想起來),而'_STACK [DECK]'就不必也改變。不管怎樣,謝謝。 – BeeBand 2010-04-04 20:04:06

2

並不清楚你所問什麼 - 考慮下面的代碼:

#include <iostream> 
#include "boost/shared_ptr.hpp" 
using namespace std; 

struct A { 
    virtual ~A() { 
     cout << "destroyed" << endl; 
    } 
}; 

struct B : public A { 
}; 

int main() { 
    boost::shared_ptr<B> b(new B); 
    boost::shared_ptr<A> a; 
    a = b; 
} 

只有一個「消滅」的消息,表示沒有複製已成功完成。

1

認爲問題是你在這裏分配不同的類型。 boost::shared_ptr是一個模板,即使它們中的類型是模板也不是多態的。所以發生了什麼事是你的編譯器看到從boost::shared_ptr<Deck>boost::shared_ptr<CardStack>的分配,並注意到它可以通過調用CardStack的複製構造函數來複制Deck對象來進行分配。

我想你想分配的樣子是這樣的:

_stack[0] = boost::static_pointer_cast<CardStack>(_deck); 

這將做轉換你期望的方式。

+0

我試過你的解決方案,但沒有喜悅。 – BeeBand 2010-04-04 17:27:17

+0

@BeeBand - 我只是注意到你更新了這個問題,並且你已經驗證它沒有調用複製構造函數。在這種情況下,上述技術將無濟於事。 – 2010-04-04 17:55:21

1

我想你可能想shared_array_stack。 。 。看看文件上shared_ptr;從boost.org,具體如下:

http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/shared_ptr.htm

「通常情況下,一個shared_ptr不能 正確把握一個指向 動態分配的數組見 shared_array了點。用法。」

另外要注意的T* get()功能(不是沒有很好的理由來使用),它返回正在舉行的託管指針的原始指針(的shared_ptr在這種情況下)。

+0

'CardStack'基本上是一個'std :: deque '的包裝。 'shared_array'仍然適用嗎? – BeeBand 2010-04-04 19:45:02

+0

它的確如果你有一個shared_ptr到你的代碼中的數組。我可能誤解了。 。 。 – 2010-04-04 21:06:18

相關問題