从没有虚拟方法的基类继承不好的做法?

时间:2011-08-09 14:28:41

标签: c++ inheritance

我回答有关dynamic_cast的问题时回答了一段时间。 dynamic_cast无法工作,因为基类没有虚方法。其中一个答案说,从没有虚拟方法的类派生通常意味着糟糕的设计。它是否正确?即使没有利用多态性,我仍然看不出这样做的错误。

5 个答案:

答案 0 :(得分:7)

这取决于我们所说的:

  • 对于Traits类(没有数据)没关系(std::unary_function浮现在脑海中)
  • 用于private继承(用于代替组合以从空基优化中受益)它也很好

当您开始以多态方式处理此类Derived对象时,问题就来了。如果你达到这样的位置,那么它就是明确的代码味道

注意:即使上面提到的很好,你仍然可以提供多态地使用该类的能力,从而使你自己暴露于微妙的错误。

答案 1 :(得分:2)

为了代码重用,从类派生始终是一个有效的选项。

有时,我们并不是在寻找多态行为。没关系 - 我们有这个选择的原因。如果是这种情况,那么考虑使用私有继承 - 如果你的类不是多态的,那么没有理由让任何人尝试多态地使用它。

答案 2 :(得分:1)

这是一个很好的例子,将行为分解为策略(注意受保护的析构函数):

struct some_policy
{
    // Some non-virtual interface here
protected:
    ~some_policy() { ... }

private:
    // Some state here
};

struct some_class : some_policy, some_other_policy { ... };

另一个好例子,避免模板中的代码膨胀。请注意受保护的析构函数:

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> { ... };

根据经验,您继承的类应该具有虚拟或受保护的析构函数。

答案 3 :(得分:0)

C ++中没有虚方法的继承只不过是代码重用。 没有多态性,我想不到继承。

答案 4 :(得分:0)

C ++标准库中的某些类具有受保护的成员(仅对派生类有意义)但没有虚拟成员函数。即,它们是为衍生而设计的,没有虚拟。这证明从一个没有虚拟的类中派生出来一般都是糟糕的设计。

干杯&amp;第h。,