23 December 2022

C++ 核心指南目录

C.137: Use virtual bases to avoid overly general base classes

理由

虚函数可以实现数据共享和接口分离。从而避免把所有共享数据放进一个最基础的基类。

例子

struct Interface {
    virtual void f();
    virtual int g();
    // ... no data here ...
};

class Utility {  // with data
    void utility1();
    virtual void utility2();    // customization point
public:
    int x;
    int y;
};

class Derive1 : public Interface, virtual protected Utility {
    // override Interface functions
    // Maybe override Utility virtual functions
    // ...
};

class Derive2 : public Interface, virtual protected Utility {
    // override Interface functions
    // Maybe override Utility virtual functions
    // ...
};

如果很多派生类共享某些明显的实现细节,可以抽取出实用功能( Utility )。

注意

显然,这个例子太理论化了。但是很难找到更小的现实例子。 Interface 是接口层级的根节点, Utility 是实现层级的根节点。

注意

更好的方案可以是线性化的继承层级。

强化

  • 标注混合了接口和实现继承层级的地方