从具有非虚拟析构函数的容器继承
我正在尝试使用前向声明和 d 指针来消除一些包含依赖项。一切都运行良好,除了我在许多地方使用了 XList typedef 来提高可读性(例如:typedef QList
)。
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
让我们看看如果我们这样定义
XList
会发生什么:以下内容将按预期工作:
但是以下内容不会:
QList
的析构函数将被调用,但不会调用 XList(如果有)。这就是基类中的虚拟析构函数将为您做的事情。如果你从不使用堆分配,你应该没问题,但你正在为跟随你的维护者(甚至几个月后的你自己)准备一个陷阱。
确保记录此假设,并将
XList
的new
运算符设为私有,以防止您提到的堆实例化。安全的替代方案是使
QList
成为XList
的成员,即:更喜欢封装而不是继承。Let's have a look at what will happen if we define
XList
this way:The following will work as expected:
However the following won't:
QList<X>
's destructor will be called but notXList
'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
'snew
operator private to prevent heap instantiation as you mentioned.The safe alternative would be making
QList<X>
a member of yourXList
, that is: prefer encapsulation to inheritance.QStringList
没有定义自己的析构函数。在这种情况下,即使QList
被多态地使用(参见 blue.tuxedo 的示例),也不会出现问题,因为即使派生类析构函数不会被调用,也没有定义一个析构函数。 。就您而言,如果您需要在派生类 (
XList
) 中使用析构函数,您将遇到问题。之前有过关于如何解决无法转发声明类型定义的问题:C++ 中 typedef 的前向声明
如果您可以避免编写派生类,从长远来看,您的情况可能会更好。
QStringList
doesn't define its own destructor. In this case, even ifQList
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.