使用抽象类作为模板类型

时间:2009-08-10 19:41:04

标签: c++ inheritance abstract-class

我仍然是c ++的新手(来自java)。 我有一个类型Actor的stl列表。当Actor仅包含“真实”方法时,没有问题。我现在想要将这个类扩展到几个类,并且需要将一些方法改为抽象,因为它们不再具体了。

正如我预期的那样(来自文档)这是坏消息,因为你无法再实例化Actor,所以当我遍历我的列表时,我遇到了问题。

c ++的方法是什么?

对不起,如果有什么不清楚的话

3 个答案:

答案 0 :(得分:6)

您无法直接处理此问题:

正如您所看到的,当课程是抽象的时,您无法实现该对象 即使不抽象的类,由于切片问题,也无法将派生对象放入列表中 解决方案是使用指针。

所以第一个问题是谁拥有指针(所有者在其生命时间结束时删除它的责任能力)。

使用std :: list<>该列表通过创建对象的副本并获取副本的所有权来获得所有权。但是指针的析构函数什么都不做。您需要手动调用指针上的delete来获取要激活的obejct的析构函数。所以std :: list<>当它还需要拥有所有权时,它不是保持指针的好选择。

解决方案1:

// Objects are owned by the scope, the list just holds apointer.
ActorD1   a1; Actor D1 derived from Actor
ActorD2   a2;
ActorD2   a3;

std::list<Actor*>  actorList;
actorList.push_back(&a1);
actorList.push_back(&a2);
actorList.push_back(&a3);

这样可以正常工作,因为列表将超出范围,然后对象一切正常。但这对于动态(运行时)创建的对象来说并不是很有用。

解决方案2:

Boost提供了一组处理指针的容器。你赋予容器指针的所有权,当容器超出范围时,容器会破坏对象。

boost::ptr_list<Actor>  actorList;

actorList.push_back(new ActorD1);
actorList.push_back(new ActorD2);
actorList.push_back(new ActorD2);

答案 1 :(得分:2)

如果Actor类型是抽象的,则无法创建std::list<Actor>。在引擎盖下,列表将包含模板参数中指定类型的实例。因为你不可能拥有抽象类的实例,所以这不会起作用。

你可以做的是使用像指针一样的间接级别。拥有指向抽象类的指针实例是合法的,因此合法地生成stl::list<Actor*>

答案 2 :(得分:2)

STL容器专为可复制类型而设计。您应该查看Boost pointer containers和/或smart pointers,以便在集合中存储多态类型实例。