我应该使用const引用还是boost::shared\u ptr? 我创建了一些C++类来模拟纸牌游戏作为一个学习练习。
我为SolitaireGame、CardStack(板上10堆卡片中的一堆)和一张卡片上了课。我目前的模型表明,SolitaireGame拥有104个卡片对象的向量,我称之为“鞋”。SolitaireGame还跟踪10个卡片堆栈,这些卡片堆栈本质上是存储在鞋子中的卡片对象地址的deque。牌组和手牌继承自CardStack。我通过指向存储在鞋中的原始对象的指针,将卡片从牌堆传递到手牌,再传递到级联 根据我对这个问题的回答,我不应该通过指针来传递卡片,而应该使用常量引用。原因是存储在向量中的对象可以移动其地址,因此将其地址存储在任何位置都是不可能的。我最近开始研究boost::sharedptr。人们对在这里使用共享的ptr卡有什么看法 以下是这些类的简化版本:我应该使用const引用还是boost::shared\u ptr? 我创建了一些C++类来模拟纸牌游戏作为一个学习练习。,c++,boost,reference,C++,Boost,Reference,我为SolitaireGame、CardStack(板上10堆卡片中的一堆)和一张卡片上了课。我目前的模型表明,SolitaireGame拥有104个卡片对象的向量,我称之为“鞋”。SolitaireGame还跟踪10个卡片堆栈,这些卡片堆栈本质上是存储在鞋子中的卡片对象地址的deque。牌组和手牌继承自CardStack。我通过指向存储在鞋中的原始对象的指针,将卡片从牌堆传递到手牌,再传递到级联 根据我对这个问题的回答,我不应该通过指针来传递卡片,而应该使用常量引用。原因是存储在向量中的对象可
class SolitaireGame
{
public:
SolitaireGame::SolitaireGame( int numsuits );
private:
vector<Card> _shoe;
Deck _deck;
Hand _hand;
CardStack _cols[NUM_COLUMNS];
int _numsuits;
GameState gamestate;
};
class CardStack
{
public:
CardStack(){ cout << "CardStack constructor" << endl; }
CardStack( const CardStack& );
CardStack( const deque<Card *> &d );
~CardStack(){ }
virtual Card * PullCard( Face f );
virtual void PushCard( Card * c );
Card * CardAt( int i ) const;
Card * Top() const;
deque<Card *>::iterator Begin() { return _cards.begin(); }
deque<Card *>::iterator End() { return _cards.end(); }
int Size() const;
CardStack& operator=( const CardStack& rhs );
friend std::ostream& operator<<(std::ostream &os, const CardStack &obj);
private:
deque<Card *> _cards;
class-SolitaireGame
{
公众:
SolitaireGame::SolitaireGame(int numsuits);
私人:
矢量鞋;
甲板;
手,手,;
CardStack_cols[NUM_COLUMNS];
国际货币基金组织;
配子状态配子状态;
};
类卡片堆栈
{
公众:
CardStack(){cout您不能将引用存储在容器中,因此如果您想要共享访问,您只能使用指针。shared\u ptr
似乎有些无意义,因为您不希望管理内存
但是,如果我创建了一个Card类,它将只包含一个或两个整数,并且它是不可变的(除非这些是可以改变其套色和价值的魔法卡)。因此,我只使用卡的副本
当您返回时,您可能更喜欢引用(除非您希望存储指向返回值的指针,这最终看起来很奇怪)。但就个人而言,我还是会按值返回。如果您要获取
vector<Card> _shoe;
vector\u鞋;
然后把它们放进你的
deque<Card *> _cards;
deque\u卡;
正如你所描述的,肯定会有问题。你的向量可能会重新分配,使得向量的卡片元素的地址不再有效
将引用(const或其他)传递给vector的内容将有与指针相通的相同问题。在C++中,引用实际上是一个较薄的指针。唯一的区别是指针如何使用(作为别名)它不能被“un坐下”的事实。,即设置为NULL,并且它与别名类型不可区分(不能有卡片引用向量)。引用没有任何特殊的引用计数或其他垃圾收集语言所获得的任何内容。因此,当向量重新分配时,如果有人持有对组中任何卡片的引用,这些引用将像指针一样容易失败
用boost::shared_ptr的向量替换你的向量可以解决你的问题。boost::shared_ptr是引用计数的。这意味着它可以跟踪底层对象存在多少引用者。你的向量将是共享_ptr的向量,而不是对象本身。因此,当向量重新分配时,你只需添加在重新分配期间,将一个新的引用暂时返回到基础对象,然后向量将用居住在重新分配空间中的共享\u ptr替换共享\u ptr。基础对象不移动
我会更进一步,并建议不要给每个人一个共享的\u ptr。传递给非所有者。boost::薄弱的\u ptr是对底层数据的弱引用。薄弱的\u ptr在需要时给某人一个句柄来获取共享的\u ptr。它不参与底层数据的引用计数。因此,您可以首先检查所有者删除了基础数据。如果未删除,则获取共享的_ptr(临时参与推荐人计数)并执行所需的操作
原因是存储在向量中的对象可以移动其地址,因此将其地址存储在任何位置都是不允许的
出于同样的原因,存储(const)引用与存储指针一样糟糕。如果只要其他对象持有指向其中对象的指针,向量的大小就不会改变,那么您应该是安全的
在C++中编程时,你应该总是决定谁拥有“对象”,例如当它不再需要时,谁负责删除它。如果没有自然对象拥有者,你可以求助于像“代码> Boo::SydDypTr< /Cuth>之类的智能指针,它使用引用计数或垃圾收集来管理对象的生存期。
在您的例子中,很明显,
SolitaryGame
实例拥有所有的牌。此外,游戏中的牌数是固定的。因此,您可以轻松地将牌的指针传递给依赖于游戏实例的对象
一旦游戏被删除,所有的卡牌都将被删除,剩余的指针将无效,但此时,持有卡牌指针的其他对象也应该被删除。我认为费迪南德上面的答案是正确的,但我想就boost::shared_ptr在本例中的使用发表评论
你的卡片对象有多重?如果它们足够小(比如说几个int),那么复制卡片本身可能比使用boost::shared_ptr更好,因为复制boost::shared_ptr并不便宜(因为引用计数上的线程同步)。这取决于您的卡牌对象不需要具有唯一的标识,例如,黑桃十张卡牌对象与其他卡牌对象一样好。感谢您的回复Ferdindand。是的,这是我设想的工作方式,游戏一被删除,卡牌就被删除,但这是可以的,因为