提问人:Luchian Grigore 提问时间:8/9/2011 更新时间:8/9/2011 访问量:7590
从没有虚拟方法的基类继承是不好的做法吗?
Is inheritance from a base class with no virtual methods bad practice?
问:
我读过一个关于dynamic_cast的问题的答案。dynamic_cast无法工作,因为基类没有虚拟方法。其中一个答案是,从没有虚拟方法的类派生通常意味着糟糕的设计。这是正确的吗?即使没有利用多态性,我仍然看不出这样做有什么错误。
答:
这取决于我们在说什么:
- 对于 Traits 类(无数据),这很好(我想到)
std::unary_function
- 对于继承(用于代替组合以从空基础优化中受益)也很好
private
当您开始以多态方式处理此类 Derived 对象时,问题就来了。如果你曾经达到这样的位置,那么它肯定是代码味道。
注意:即使上面指出的很好,您仍然提供了以多态方式使用该类的能力,因此您将自己暴露在微妙的错误中。
评论
private
在 C++ 中没有虚拟方法的继承只不过是代码重用。 我想不出没有多态性的继承。
为了代码重用,从类派生始终是一个有效的选项。
有时,我们不是在寻找多态性行为。没关系 - 我们有这个选择是有原因的。但是,如果是这种情况,那么请考虑改用私有继承 - 如果你的类不是多态的,那么任何人都没有理由尝试多态使用它。
评论
using
public
protected
下面是一个 OK 示例,用于将行为因素分解到策略中(请注意受保护的析构函数):
struct some_policy
{
// Some non-virtual interface here
protected:
~some_policy() { ... }
private:
// Some state here
};
struct some_class : some_policy, some_other_policy { ... };
另一个 Ok 示例,以避免模板中的代码膨胀。请注意受保护的析构函数:
struct base_vector
{
// Put everything which doesn't depend
// on a template parameter here
protected:
~base_vector() { ... }
};
template <typename T>
struct vector : base_vector
{ ... };
另一个例子,称为 CRTP。请注意受保护的析构函数:
template <typename Base>
struct some_concept
{
void do_something { static_cast<Base*>(this)->do_some_other_thing(); }
protected:
~some_concept() { ... }
};
struct some_class : some_concept<some_class> { ... };
另一个例子,称为空基地优化。本身并不是真正的继承,因为它更像是一种技巧,允许编译器不为基类(充当私有成员)保留任何空间。some_class
template <typename T>
struct some_state_which_can_be_empty { ... };
template <typename T>
struct some_class : private some_state_which_can_be_empty<T> { ... };
根据经验,您继承的类应该具有虚拟析构函数或受保护的析构函数。
评论
public
C++ 标准库中的某些类具有受保护的成员(仅对派生类有意义),但没有虚拟成员函数。也就是说,它们是为派生而设计的,没有虚拟。这证明,从没有虚拟的类派生出来通常一定是糟糕的设计。
干杯 & hth.,
上一个:C 语言中的虚函数 [重复]
评论