基础和继承对象的向量

时间:2015-08-01 09:15:51

标签: c++ inheritance vector

如何创建包含基类和任何派生类的向量?

例如,在国际象棋引擎中,我目前有一个Move类,它存储一个特定的动作和一些功能来帮助它。为了节省内存,因为将要创建数百万个这样的对象,我还有一个派生类CaptureMove,它扩展了Move类,存储了有关捕获的内容和位置的更多信息

从我可以收集到的内容中,指向Move对象的指针应该有效,但我不太清楚如何去做。

1 个答案:

答案 0 :(得分:1)

问题非常广泛。这里有一些想法:

基本指针的向量:

如果您的类是多态的(即基类的相关函数是虚拟的),这非常有效。

vector<Move*> mp; 
mp.push_back (new Move);     // attention, you have to delete it ofr memory will leak
mp.push_back (new CaptureMove);

这是最简单的方法。但是,您必须确保在添加对象时,它已正确分配(例如,使用new创建),并且一旦您不再需要它,您将删除它。这可能非常麻烦,特别是如果复制了vector并且它的一些指针仍在使用中。

例如,如果以集中方式创建和删除对象,则此方法很实用,因此向量仅使用在其他位置正确管理的指针。

共享基本指针的向量:

vector<shared_ptr<Move>> m; 
m.push_back(make_shared<Move>());
m.push_back(make_shared<CaptureMove>());
m.push_back(make_shared<Move>());

这是online demo

它扩展了指针解决方案,使用智能指针来处理未使用对象的释放。

老实说,它有点开销,但为了拥有可靠的代码,它确实值得。如果我必须这样做,这是我个人采取的方法。

复合对象的矢量

您也可以更喜欢存储对象而不是指向对象的指针。虽然这个想法看起来很简单,但这样做更难,因为不同的衍生物可能有不同的大小。它有严重的缺点,因为你需要知道你可能存储在向量中的所有可能的基类和派生类型,这使得这种方法不那么灵活。

你当然可以通过一个复杂的联合来管理它,但更简单的方法是使用boost::variant

vector<boost::variant<Move, CaptureMove>> m; 

这种方法只值得考虑,如果派生类的数量非常有限,但你有大量的小对象(因此内存分配将成为一个真正的开销)几乎相同的大小。

相关问题