2010-04-04 57 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

相关问题