从没有虚拟析构函数的类继承 [英] Inheriting from classes without virtual destructors

查看:101
本文介绍了从没有虚拟析构函数的类继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直听说你不应该从没有虚拟析构函数的类继承而且我没注意太多,因为我只是不经常使用继承。即使您不想使用多态,此规则也适用,但您只想要所有类功能,并且还想添加更多功能?具体来说,只要我没有多态地使用它,下面的类是否安全,具有明确定义的行为? (即没有删除派生对象的基本指针)

I've always heard that you shouldn't inherit from a class without virtual destructors, and I didn't pay much attention because I just don't use inheritance all that often. Does this rule apply even if you don't want to use polymorphism, but you just want all of a class functionality, and you want to add some more? To be concrete, would the following class be safe, with well defined behavior, as long as I didn't use it polymorphically? (i.e. no deleting base pointers to derived objects)

template<typename T>
class SomewhatSafeVector : public std::vector<T>
{
public:
    typedef std::vector<T> base;

    T& operator[](unsigned n) {
        if (n >= base::size())
        {
            throw IndexOutOfBounds();
        }
        return base::operator[](n);
    }
};


推荐答案


我一直都是听说你不应该从没有虚拟析构函数的类继承

I've always heard that you shouldn't inherit from a class without virtual destructors

这是给初学者的一个经验法则,因为它解释了所有错综复杂的错误需要花费太多时间,而且实际上只给他们一些基线,这些基线在所有时间都有效(但可能有点矫枉过正),这对于锻炼计划而言更安全(而且并不是那么昂贵)。

This is a rule of thumb given to beginners because explaining all the intricacies take too much time and it is just safer (and not that much costly for exercices programs) to actually give them just a few base lines that work all the times (though may be overkill).

在基类中没有虚拟析构函数的情况下,您可以完美地使用继承。另一方面,如果基类根本没有虚拟方法,那么继承可能是该作业的错误工具。 例如:如果我使用 SafeVector< T> SV; sv [3]; 那么它是安全的,但是如果我做 std :: vector< T>& v = sv; v [3]; 它不是......这是因为你只是隐藏基类方法,而不是覆盖它(提高你的警告水平,他们会让你知道)。

You can perfectly use inheritance without a virtual destructor in the base class. On the other hand, if the base class has no virtual method at all, then inheritance is probably the wrong tool for the job. For example: in your case if I use SafeVector<T> sv; sv[3]; then it is safe, however if I do std::vector<T>& v = sv; v[3]; it is not... this is because you are merely hiding the base class method, not overriding it (crank up your warning level, they'll let you know).

这里的正确方法是使用组合,然后为你真正使用的那些方法创建实现成员的转发方法。在实践中,它变得很累,因为C ++不支持委托(使用attribute.insert; ),所以很多人诉诸继承......

The proper way here would be to use composition, and then create forwarding methods to the implementation member for those methods you really use. In practice, it gets tiring because C++ does not support delegation (using attribute.insert;) so many resort to inheriting...

另一种方法是提供更安全的方法作为免费方法,因为你总是可以无限制地添加免费方法。对于具有OO心态的人来说,这可能会让人觉得不那么惯用,而且有些运营商也不能这么做。

Another alternative is to provide the safer methods as free methods, since you can always add free methods without restriction. It might feel less idiomatic to people with the "OO" mindset, and some operators cannot be so added.

这篇关于从没有虚拟析构函数的类继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆