C++ 纯虚类中的构造函数应该是“protected”还是“public”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24037038/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:37:14  来源:igfitidea点击:

The constructor function in a pure virtual class should be "protected" or "public"?

c++oopinheritanceconstructorpure-virtual

提问by Wizmann

The following example is from the book "Inside C++ object model"

下面的例子来自《Inside C++ object model》一书

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

The author says if I want to initialize _mumble, the data member of the pure virtual base class, a "protected constructor"should be implemented.

作者说如果要初始化_mumble纯虚基类的数据成员,应该实现一个“受保护的构造函数”

But why protected? And why "public constructor"is not suitable for this class?

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

Thanks for your answers, and it would be perfect if there's an example~~ :)

谢谢你的回答,如果有例子就完美了~~ :)

采纳答案by Fred Foo

It doesn't really matter, since you're not allowed to construct objects of the base class anyway. Making it protectedserves only as a reminder of the fact that the class is supposed to be a base class; it's only cosmetics/documentation.

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

Consider

考虑

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;
}

Removing the protecteddoesn't change the meaning of the program in any way.

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

回答by Filip Roséen - refp

Abstract classes and construction of such

抽象类及其构造

It doesn't matter if the constructor is publicor protected, since an abstract classcannot be instantiated.

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

You must inherit from it in order to have it's constructor called, and since the Derivedclass calls the constructor of the abstract classit doesn't matter what protection level you choose, as long as the Derivedclass can access it.

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



One reason that one could possibly have for making it protectedis to serve as a reminder that the class must be constructed through inheritance, but honestly that should be clear enough when seeing that it has pure virtualmember-functions.

制作它的一个可能原因protected是提醒类必须通过继承构造,但老实说,当看到它具有纯虚拟成员函数时,这应该足够清楚了。



example snippet

示例片段

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 ()`
}

回答by jsantander

A pure virtual class cannot be instantiated, so it doesn't make a difference if the constructor is public or protected.

纯虚拟类无法实例化,因此构造函数是公共的还是受保护的都没有区别。

A public constructor is syntactically correct. However, making it protected will carry a stronger indicationthat the class cannot be instantiated.

公共构造函数在语法上是正确的。但是,使其受保护将带有更强的指示表明该类不能被实例化。

For an example: http://ideone.com/L66Prq

例如: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;
}

回答by Frédéric Hamidi

A public constructor would not be very useful, since abstract classes cannot be instantiated in the first place.

公共构造函数不是很有用,因为抽象类首先不能被实例化。

A protected constructor makes sense: this way, a derived concrete class can provide its own public constructor that chains to the protected constructor of the base abstract class.

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

回答by CinCout

Protecetd ctorwill make sure the ctor gets called by only the classes which derive from Abstract_base.

Protecetd ctor将确保仅由派生自Abstract_base.

Public ctoris not suitable because the class contains a pure virtualmethod! How are you planning to instantiate a pure-virtual class if not via its child classes?

公共 ctor不合适,因为该类包含一个pure virtual方法!如果不通过其子类,您打算如何实例化纯虚拟类?