纯虚拟类中的构造函数应该是“受保护的”还是“公共的”?

时间:2014-06-04 12:07:18

标签: c++ oop inheritance constructor pure-virtual

以下示例来自本书“Inside C ++对象模型”

class Abstract_base {
public:
    virtual ~Abstract_base () = 0;
    virtual void interface () const = 0;
    virtual const char* mumble () const 
    {
        return _mumble;
    }
protected:
    char *_mumble;
};

作者说如果我想初始化_mumble,那么应该实现纯虚拟基类的数据成员,“protected constructor”

但为什么受保护?为什么“公共构造函数”不适合这个类?

感谢您的回答,如果有一个例子,那将是完美的~~:)

5 个答案:

答案 0 :(得分:6)

它并不重要,因为你无论如何都不允许构造基类的对象。使它成为protected只是为了提醒一下这个类应该是一个基类;它只是化妆品/文件。

考虑

struct Base {
    virtual ~Base() = 0;
  protected:
    Base() { std::puts("Base constructor"); }
};

Base::~Base() { std::puts("Base destructor"); }

struct Derived : Base {};

int main()
{
    //Base b;   // compiler error
    Derived d;

    Base *b = new Derived();
    delete b;
}

删除protected并不会以任何方式更改程序的含义。

答案 1 :(得分:5)

抽象类和

的构造

构造函数是 public 还是 protected 并不重要,因为抽象类无法实例化。

您必须继承它才能调用它的构造函数,并且由于 Derived 类调用抽象类的构造函数,因此保护级别无关紧要您选择,只要派生类可以访问它。


一个人可能拥有它protected的原因之一就是提醒我们必须通过继承构建类,但老实说,当它看到纯虚拟时,应该足够明确成员函数。


示例代码段

struct B {
  virtual void func () = 0;
  virtual ~B () = 0 { };
};

B::~B () { }

struct D : B {
  void func () override;
};

int main () {
  B b; // will error, no matter if Bs ctor is 'public' or 'protected'
       // due to pure virtual member-function

  D d; // legal, D has overriden `void B::func ()`
}

答案 2 :(得分:3)

纯虚拟类无法实例化,因此如果构造函数是公共的或受保护的,它就不会产生影响。

公共构造函数在语法上是正确的。但是,保护它会带来更强的指示,无法实例化该类。

例如:http://ideone.com/L66Prq

#include <iostream>
using namespace std;

class PublicAbstract {
public:
    PublicAbstract() { }        
    virtual void doThings() =0;
};

class ProtectedAbstract {
protected:
    ProtectedAbstract() { }     
public:
    virtual void doMoreThings() =0;
};

class B: public PublicAbstract {
public:
    void doThings() { } 
};

class C: public ProtectedAbstract {
public:
    void doMoreThings() { } 
};

int main() {
    B b;
    C c;
    return 0;
}

答案 3 :(得分:2)

公共构造函数不会非常有用,因为抽象类首先无法实例化。

受保护的构造函数是有道理的:这样,派生的具体类可以提供自己的公共构造函数,该构造函数链接到基本抽象类的受保护构造函数。

答案 4 :(得分:0)

Protecetd ctor 将确保仅由Abstract_base派生的类调用ctor。

Public ctor 不适合,因为该类包含pure virtual方法!如果没有通过子类,你打算如何实例化纯虚拟类?