当父项受保护时,我对继承类的默认构造函数有疑问,在我看来,子类也有一个默认的受保护类,但事实并非如此。
是否有办法强制默认构造函数受到保护,而不是强制它在子类上?
C ++ 11 - gcc version 5.3.1 20151219(Debian 5.3.1-4)。
int main ( int argc, char ** argv )
{
using namespace std;
class A
{
public:
static std::shared_ptr<A> CreateInstance ()
{
A * pInstance { new A };
return { pInstance, []( A * pInstance )
{
delete pInstance;
}};
};
protected:
A () = default;
~A () = default;
};
class B : public A
{
};
B b; // It's work !
return 0;
}
感谢您的帮助,
减灾会议
答案 0 :(得分:1)
不,即使基类构造函数受到保护,派生类'自动生成的默认构造函数仍然是公共的。
有两种方法(我可以想到)防止派生类B直接可实例化:
这可以通过提供一个带伪参数的构造函数来实现:
class A
{
public:
// ...
protected:
A (int) {}
};
class B : public A
{
};
B b; // error: B::B()' is implicitly deleted because the
// default definition would be ill-formed
实例化B将失败,因为B的自动生成的默认构造函数将尝试使用A的默认构造函数,该构造函数不存在。
但这很容易被规避:
class B : public A
{
public:
B() : A(0) {}
}
B b; // works
class B
{
// ...
protected:
B() = default;
}
选项(2)对于阅读代码的其他人来说是最不令人惊讶的,并且是我推荐的选项。任何熟悉静态createFoo
工厂函数的人都会理解为什么构造函数是私有的或受保护的。
修改强>
在类层次结构中使用静态create
工厂函数时,常见的习惯用法是为派生类提供静态create
工厂函数,并使其构造函数为私有或受保护。
派生类不应使用基类的create
工厂函数。它们应该隐式或显式地调用基类构造函数。
class Base
{
public:
static shared_ptr<Base> create()
{
return shared_ptr<Base>(new Base);
}
protected:
Base() {...}
};
class Derived
{
public:
static shared_ptr<Derived> create()
{
return shared_ptr<Derived>(new Derived);
}
protected:
Derived() {...} // Implicitly calls base class default constructor
};
// Usage
auto b = Base::create();
auto d = Derived::create();