使用抽象类作为模板类型

发布于 2024-08-01 15:12:01 字数 281 浏览 5 评论 0原文

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

正如我(从文档中)预期的那样,这是个坏消息,因为您无法再实例化 Actor,因此当我迭代列表时,我遇到了问题。

C++ 的方法是什么?

抱歉,如果有任何不清楚的地方

I'm still pretty new to c++ (coming over from java).
I have a stl list of type Actor. When Actor only contained "real" methods there was no problem. I now want to extend this class to several classes, and have a need to change some methods to be abstract, since they don't make sense as concrete anymore.

As I expected (from the documentation) this is bad news because you can no longer instantiate Actor, and so when I iterate through my list I run into problems.

What is the c++ way to do this?

Sorry if there's anything unclear

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情愿 2024-08-08 15:12:01

您无法直接处理此问题:

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

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

使用 std::list<> 该列表通过创建对象的副本并取得该副本的所有权来获得所有权。 但指针的析构函数不执行任何操作。 您需要手动调用指针上的删除来激活对象的析构函数。 所以 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);

You can not handle this directly:

As you can see when the class is abstract you can not instanciate the object.
Even if the class where not abstract you would not be able to put derived objects into the list because of the slicing problem.
The solution is to use pointers.

So the first question is who owns the pointer (it is the responcability of the owner to delete it when its life time is over).

With a std::list<> the list took ownership by creating a copy of the object and taking ownership of the copy. But the destructor of a pointer does nothing. You need to manually call the delete on a pointer to get the destructor of the obejct to activate. So std::list<> is not a good option for holding pointers when it also needs to take ownership.

Solution 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);

This works fine as the list will go out of scope then the objects everything works fine. But this is not very useful for dynamically (run-time) created objects.

Solution 2:

Boost provides a set of containers that handle pointers. You give ownership of the pointer to the container and the object is destroyed by the containter when the container goes out ofd scope.

boost::ptr_list<Actor>  actorList;

actorList.push_back(new ActorD1);
actorList.push_back(new ActorD2);
actorList.push_back(new ActorD2);
表情可笑 2024-08-08 15:12:01

如果 Actor 类型是抽象的,则无法创建 std::list。 在底层,列表将保存模板参数中指定类型的实例。 因为你永远不可能拥有抽象类的实例,所以这是行不通的。

不过,您可以做的是使用像指针这样的间接级别。 拥有指向抽象类的指针实例是合法的,因此创建 stl::list 也是合法的。

It's not possible to create a std::list<Actor> if the type Actor is abstract. Under the hood a list will hold an instance of the type specified in the template arguments. Because you can't ever have an instance of an abstract class this won't ever work.

What you can do though is use a level of indirection like a pointer. It is legal to have an instance of a pointer to an abstract class and hence legal to make a stl::list<Actor*>.

ˉ厌 2024-08-08 15:12:01

STL 容器是为可复制类型而设计的。 您应该研究 Boost 指针容器 和/或智能指针用于存储多态类型实例一个集合。

STL containers are designed for copyable types. You should look into Boost pointer containers and/or smart pointers for storing polymorphic type instances in a collection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文