0

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

typedef 前向声明问题的解决方法是使用继承:class XList : public QList<X>{};. QList 有一个非虚拟析构函数。考虑到 Qt 自己的 QStringList 继承QList<QString>并且我没有在堆上分配 XLists 的事实,您认为这种解决方法有什么问题吗?我应该明确禁止 XList 类的堆分配吗?

4

2 回答 2

1

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

class XList : public QList<X> {};

以下将按预期工作:

  XList* x = new XList;
  delete x;

但是以下不会:

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

QList<X>的析构函数将被调用,但不是XList',如果有的话。这就是基类中的虚拟析构函数将为您做的事情。

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

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

安全的选择是让QList<X>你的成员成为一个成员XList,即:更喜欢封装而不是继承。

于 2010-01-27T17:43:21.413 回答
0

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

在您的情况下,如果您在派生类 ( XList) 中需要析构函数,则会遇到问题。之前有一个关于如何解决无法在此处转发声明类型定义的讨论:

C++ 中 typedef 的前向声明

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

于 2010-01-27T17:52:19.427 回答