在C++中设计ABC(抽象基类)的好习惯

q09*_*987 3 c++ abstract-class design-patterns

在java中,我们可以定义不同的接口,然后我们可以为具体的类实现多个接口.

// Simulate Java Interface in C++
/*
interface IOne {
    void   MethodOne(int i);
    .... more functions
}

interface ITwo {
    double MethodTwo();
    ... more functions
}

class ABC implements IOne, ITwo {
    // implement MethodOne and MethodTwo
}
*/
Run Code Online (Sandbox Code Playgroud)

在C++中,一般来说,我们应该避免使用多重继承,尽管多继承确实在某些情况下具有优势.

class ABC {
public:
    virtual void   MethodOne(int /*i*/) = 0 {}
    virtual double MethodTwo() = 0 {}

    virtual ~ABC() = 0 {}

protected:
    ABC() {} // ONLY ABC or subclass can access it
};
Run Code Online (Sandbox Code Playgroud)

问题1 >基于设计ABC,我应该改进其他任何东西,以使其成为一个体面的ABC?

问题2 >商品是否ABC应该包含成员变量,而变量应该保存在子类中?

问题3 >正如我在评论中指出的那样,如果ABC必须包含太多纯函数呢?有没有更好的办法?

Jam*_*lis 9

在C++中,一般来说,我们应该避免使用多重继承

与任何其他语言功能一样,您应该在适当的地方使用多重继承.接口通常被认为是多重继承的适当用法(例如,参见COM).

ABC需求的构造函数不受保护 - 它不能直接构造,因为它是抽象的.

ABC析构函数不应该被声明为纯虚函数(它应该被声明为虚拟的,当然).如果不需要派生类,则不应要求派生类实现用户声明的构造函数.

接口不应该有任何状态,因此不应该有任何成员变量,因为接口只定义了如何使用某些内容,而不是如何实现它.

ABC不应该有太多的成员职能; 它应该具有所需的数量.如果有太多,显然应该删除那些未使用或不需要的,或者将接口重构为几个更具体的接口.


小智 9

  1. 除非必要,否则不要为纯虚方法提供实现.
  2. 不要让你的析构函数纯粹虚拟.
  3. 不要让你的构造函数受到保护.您无法创建抽象类的实例.
  4. 更好地隐藏源文件中的构造函数和析构函数的实现,以免污染其他对象文件.
  5. 使您的界面不可复制.

如果这是一个接口,那么最好没有任何变量.否则它将是一个抽象基类而不是一个接口.

太多的纯函数是可以的,除非你能用较少的纯函数来完成它.