从具有非虚拟析构函数的容器继承

发布于 2024-08-19 00:51:04 字数 340 浏览 11 评论 0原文

我正在尝试使用前向声明和 d 指针来消除一些包含依赖项。一切都运行良好,除了我在许多地方使用了 XList typedef 来提高可读性(例如:typedef QListXList)。

typedef 前向声明问题的解决方法是使用继承:class XList : public QList{};。 QList 有一个非虚拟析构函数。鉴于 Qt 自己的 QStringList 继承了 QList 并且我没有在堆上分配 XList,您认为此解决方法有任何问题吗?我应该明确禁止 XList 类的堆分配吗?

I'm trying to use forward declarations and d-pointers to eliminate some include dependencies. Everything is working well, except that I have used XList typedefs for readability in many places (e.g: typedef QList<X> XList).

The workaround for the typedef forward declaration issue is to use inheritance: class XList : public QList<X>{};.
QList has a non-virtual destructor. Given the fact that Qt's own QStringList inherits QList<QString> and I'm not allocating XLists on the heap, do you see any problems with this workaround? Should I explicitly disallow heap allocations for the XList classes?

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

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

发布评论

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

评论(2

極樂鬼 2024-08-26 00:51:04

让我们看看如果我们这样定义 XList 会发生什么:

class XList : public QList<X> {};

以下内容将按预期工作:

  XList* x = new XList;
  delete x;

但是以下内容不会:

  QList<X>* q = new XList;
  delete q;

QList 的析构函数将被调用,但不会调用 XList(如果有)。这就是基类中的虚拟析构函数将为您做的事情。

如果你从不使用堆分配,你应该没问题,但你正在为跟随你的维护者(甚至几个月后的你自己)准备一个陷阱。

确保记录此假设,并将 XListnew 运算符设为私有,以防止您提到的堆实例化。

安全的替代方案是使 QList 成为 XList 的成员,即:更喜欢封装而不是继承。

Let's have a look at what will happen if we define XList this way:

class XList : public QList<X> {};

The following will work as expected:

  XList* x = new XList;
  delete x;

However the following won't:

  QList<X>* q = new XList;
  delete q;

QList<X>'s destructor will be called but not XList's, if any. That's what a virtual destructor in the base class will do for you.

If you never use heap allocations you should be fine, but you're preparing a trap for the maintainer following you (or even yourself in a few months).

Make sure this assumption is documented and make XList's new operator private to prevent heap instantiation as you mentioned.

The safe alternative would be making QList<X> a member of your XList, that is: prefer encapsulation to inheritance.

红尘作伴 2024-08-26 00:51:04

QStringList 没有定义自己的析构函数。在这种情况下,即使 QList 被多态地使用(参见 blue.tuxedo 的示例),也不会出现问题,因为即使派生类析构函数不会被调用,也没有定义一个析构函数。 。

就您而言,如果您需要在派生类 (XList) 中使用析构函数,您将遇到问题。之前有过关于如何解决无法转发声明类型定义的问题:

C++ 中 typedef 的前向声明

如果您可以避免编写派生类,从长远来看,您的情况可能会更好。

QStringList doesn't define its own destructor. In this case, even if QList was used polymorphically (see blue.tuxedo's example), there isn't a problem since even though the derived class destructor won't get called, there isn't one defined.

In your case, if you require a destructor in your derived class (XList), you'll run into problems. There was a previous discussion about how to get around not being able to forward declare type definitions here:

Forward declaration of a typedef in C++

If you can avoid writing a derived class, you might be better off in the long run.

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