如何创建一个既包含基类又包含任何派生类的 vector ?
例如,在国际象棋引擎中,我目前有一个 Move
类,它存储一个特定的 Action 和一些帮助它的函数。为了节省内存,因为将要创建数百万个这样的对象,我还有一个派生类 CaptureMove
扩展了 Move
类,存储更多关于什么的信息以及这件作品的拍摄地点。
据我所知,指向 Move
对象的指针应该可以工作,但我不太确定如何去做。
最佳答案
这个问题很宽泛。这里有一些想法:
基指针 vector :
如果您的类是多态的(即基类的相关函数是虚拟的),这会非常有效。
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 仅使用在其他地方妥善管理的指针。
共享基指针的 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 .
它扩展了指针解决方案,使用智能指针来处理未使用对象的释放。
老实说,这有点开销,但为了拥有可靠的代码,这确实是值得的。如果我必须这样做,这是我个人会采取的方法。
复合对象的 vector
您也可以更喜欢存储对象而不是指向对象的指针。虽然这个想法看起来很简单,但做起来却比较困难,因为不同的导数可能有不同的大小。而且它有严重的缺点,因为您需要知道可能存储在 vector 中的所有可能的基类型和派生类型,这使得这种方法不太灵活。
你当然可以用一个复杂的 union 来管理它,但更简单的方法是使用 boost::variant
.
vector<boost::variant<Move, CaptureMove>> m;
只有当派生类的数量非常有限,但您有大量几乎相同大小的小对象(这样内存分配将成为真正的开销)时,才值得考虑这种方法。
关于c++ - 基础对象和继承对象的 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31760228/