参考链接: C 多重,多层和阶层式继承
C.120: Use class hierarchies to represent concepts with inherent hierarchical structure (only)
C.120:类层次体系只用于表现固有的阶层结构
Reason(原因)
Direct representation of ideas in code eases comprehension and maintenance. Make sure the idea represented in the base class exactly matches all derived types and there is not a better way to express it than using the tight coupling of inheritance.
将想法用代码直接表达使理解和维护更容易。确保用基类表现的想法准确地匹配所有的派生类型并且找不到使用继承这样的紧耦合之外更合适的方式。
Do not use inheritance when simply having a data member will do. Usually this means that the derived type needs to override a base virtual function or needs access to a protected member.
不要仅仅因为某个数据成员需要继承就使用继承。继承通常意味着派生类型需要覆盖某个基类的虚函数或者需要访问保护成员。
Example(示例)
class DrawableUIElement {
public:
virtual void render() const = 0;
// ...
};
class AbstractButton : public DrawableUIElement {
public:
virtual void onClick() = 0;
// ...
};
class PushButton : public AbstractButton {
void render() const override;
void onClick() override;
// ...
};
class Checkbox : public AbstractButton {
// ...
};
Example, bad(反面示例)
Do not represent non-hierarchical domain concepts as class hierarchies.
不要将非阶层领域的概念表现为类层次。
template<typename T>
class Container {
public:
// list operations:
virtual T& get() = 0;
virtual void put(T&) = 0;
virtual void insert(Position) = 0;
// ...
// vector operations:
virtual T& operator[](int) = 0;
virtual void sort() = 0;
// ...
// tree operations:
virtual void balance() = 0;
// ...
};
Here most overriding classes cannot implement most of the functions required in the interface well. Thus the base class becomes an implementation burden. Furthermore, the user of Container cannot rely on the member functions actually performing meaningful operations reasonably efficiently; it may throw an exception instead. Thus users have to resort to run-time checking and/or not using this (over)general interface in favor of a particular interface found by a run-time type inquiry (e.g., a dynamic_cast).
这段代码接口定义的函数大多数派生类都无法很好地实现。基类成了实现时的负担。进一步说,容器的用户实际上无法依赖成员函数合理,高效地执行有意义的操作;它可能会抛出异常。因此用户必须求助于运行时检查以便决定用或不用这个普遍的接口而选择通过动态类型查询(例如dynamic_cast)获得的特殊接口。
Enforcement(实施建议)
Look for classes with lots of members that do nothing but throw. 发现拥有大量什么也不做只会抛出异常的数据成员的类。 Flag every use of a nonpublic base class B where the derived class D does not override a virtual function or access a protected member in B, and B is not one of the following: empty, a template parameter or parameter pack of D, a class template specialized with D. 在所有使用非公开基类B而派生类D没有覆盖B的虚函数或者访问B的保护型数据成员时进行提示。其中B不属于下面的情况:空,D的模板参数或参数包,被D特化的模板类。
原文链接
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c120-use-class-hierarchies-to-represent-concepts-with-inherent-hierarchical-structure-only
觉得本文有帮助?欢迎点赞并分享给更多的人。
阅读更多更新文章,请关注微信公众号【面向对象思考】