4

我有一个班级模型:

class Model
{
    ...

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

Deck继承自CardStack

我试图通过以下方式_stack[0]指出同一件事_deck

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

似乎分配 to_deck_stack[0]导致_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();
    }   

}

现在 - 当我打电话时:

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

我得到这个输出(其中 a 上的 std::coutCardStack将打印出该堆栈的大小):

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;
};
4

4 回答 4

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;
}

只出现一条“销毁”消息,表示没有复制。

于 2010-04-04T16:58:08.130 回答
1

这个例子 - 来自@Neil的回答,试图模仿你所说的正在发生的事情。您能否检查它在您的系统上是否按预期工作(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. 引入一个同时改变两个指针的函数。
于 2010-04-04T18:10:31.653 回答
1

我想你可能 想要shared_array. _stack. . 查看来自 boost.org的文档shared_ptr,特别是:

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

“通常,shared_ptr 无法正确保存指向动态分配数组的指针。有关该用法,请参见 shared_array。”

另外,请注意T* get()返回托管指针(在本例中为 shared_ptr )持有的原始指针的函数(没有充分理由请勿使用)。

于 2010-04-04T18:43:49.763 回答
1

认为问题在于您在这里在不同类型之间进行分配。boost::shared_ptr是一个模板,模板不是多态的,即使它们中的类型是。所以发生的事情是你的编译器看到了从boost::shared_ptr<Deck>to的赋值,boost::shared_ptr<CardStack>并注意到它可以通过调用 CardStack 的复制构造函数来复制 Deck 对象来进行赋值。

我认为您希望作业看起来像这样:

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

它将按照您期望的方式进行转换。

于 2010-04-04T17:23:12.027 回答