sve*_*aro 7 c++ containers interface heterogeneous
我想管理从公共容器中的共享接口类派生的一堆类对象.
为了说明这个问题,我们假设我正在构建一个包含不同演员的游戏.让我们来调用接口IActor,并获得Enemy与Civilian如此.
现在,我的想法是让我的游戏主循环能够做到这一点:
// somewhere during init
std::vector<IActor> ActorList;
Enemy EvilGuy;
Civilian CoolGuy;
ActorList.push_back(EvilGuy);
ActorList.push_back(CoolGuy);
Run Code Online (Sandbox Code Playgroud)
和
// main loop
while(!done) {
BOOST_FOREACH(IActor CurrentActor, ActorList) {
CurrentActor.Update();
CurrentActor.Draw();
}
}
Run Code Online (Sandbox Code Playgroud)
... 或类似的规定.这个例子显然不起作用,但这就是我在这里问的原因.
我想知道:在一个通用的异构容器中管理这些对象的最佳,最安全,最高级的方法是什么?我知道各种方法(Boost :: Any,void*,带有boost :: shared_ptr的处理程序类,Boost.Pointer容器,dynamic_cast)但我无法确定哪种方法可以去这里.
另外我想强调一点,我希望尽可能远离手动内存管理或嵌套指针.
非常感谢:).
Yog*_*ora 10
要解决你提到的问题,虽然你正朝着正确的方向前进,但你做错了.这是你需要做的
Enemy和Civilian您的情况所覆盖.std::vector<IActor>不是一个好选择的因为
IActor部分而不是整个对象.EnemyCivilianvirtual functions)的类型调用函数,这只有在使用指针时才会发生.上述两个原因都表明你需要使用一个可以包含指针的容器std::vector<IActor*>.但更好的选择是使用container of smart pointers哪种方式可以避免内存管理问题.您可以根据需要使用任何智能指针(但不能auto_ptr)
这就是您的代码的样子
// somewhere during init
std::vector<some_smart_ptr<IActor> > ActorList;
ActorList.push_back(some_smart_ptr(new Enemy()));
ActorList.push_back(some_smart_ptr(new Civilian()));
Run Code Online (Sandbox Code Playgroud)
和
// main loop
while(!done)
{
BOOST_FOREACH(some_smart_ptr<IActor> CurrentActor, ActorList)
{
CurrentActor->Update();
CurrentActor->Draw();
}
}
Run Code Online (Sandbox Code Playgroud)
除了智能指针部分之外,它与原始代码非常相似
正如您所猜测的,您需要将对象存储为指针。
我更喜欢使用 boost 指针容器(而不是普通的智能指针容器)。
原因是 boost ptr 容器访问对象就像它们是对象(返回引用)而不是指针一样。这使得在容器上使用标准函子和算法变得更加容易。
智能指针的缺点是您共享所有权。
这不是你真正想要的。您希望所有权位于一个地方(在本例中为容器)。
boost::ptr_vector<IActor> ActorList;
ActorList.push_back(new Enemy());
ActorList.push_back(new Civilian());
Run Code Online (Sandbox Code Playgroud)
和
std::for_each(ActorList.begin(),
ActorList.end(),
std::mem_fun_ref(&IActor::updateDraw));
Run Code Online (Sandbox Code Playgroud)