以下示例来自本书“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”。
但为什么受保护?为什么“公共构造函数”不适合这个类?
感谢您的回答,如果有一个例子,那将是完美的~~:)
答案 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)
纯虚拟类无法实例化,因此如果构造函数是公共的或受保护的,它就不会产生影响。
公共构造函数在语法上是正确的。但是,保护它会带来更强的指示,无法实例化该类。
#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
方法!如果没有通过子类,你打算如何实例化纯虚拟类?