我之前读过一篇关于dynamic_cast的问题的答案。因为基类没有虚函数,所以dynamic_cast失败了。其中一位回答者说从没有虚函数的类派生通常意味着一个糟糕的设计。这正确吗?即使不利用多态性,我仍然看不出这样做的错误之处。
我之前读过一篇关于dynamic_cast的问题的答案。因为基类没有虚函数,所以dynamic_cast失败了。其中一位回答者说从没有虚函数的类派生通常意味着一个糟糕的设计。这正确吗?即使不利用多态性,我仍然看不出这样做的错误之处。
这要看我们讨论的是什么:
std::unary_function
)private
继承(用于从空基类优化中获益而不是组合),这也是可以接受的问题出现在你开始针对这个基类多态地处理这样的派生对象时。如果你达到了这样的位置,那么这肯定是一种代码异味。
注意:即使如上所述是可以接受的,你仍然提供了使用类多态性的能力,因此会暴露自己于微妙的错误。
从一个类派生是一种有效的选项,以便重用代码。
有时候我们不需要多态行为。这很好-我们有这个选项的原因。但如果是这种情况,那么考虑使用私有继承-如果你的类不打算成为多态的,那么没有人会试图将其作为多态来使用。
这里有一个不错的例子,将行为因素纳入策略中(请注意受保护的析构函数):
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> { ... };
C++标准库中的一些类具有受保护成员(仅对派生类有意义),但没有虚成员函数。也就是说,它们被设计用于继承,而不具备虚拟性。这证明了从一个没有虚拟成员函数的类派生通常是坏的设计。
祝好!