父级的受保护构造函数和未受保护的继承的默认构造函数

时间:2016-01-03 14:24:34

标签: c++ c++11 inheritance constructor default

当父项受保护时,我对继承类的默认构造函数有疑问,在我看来,子类也有一个默认的受保护类,但事实并非如此。

是否有办法强制默认构造函数受到保护,而不是强制它在子类上?

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

感谢您的帮助,

减灾会议

1 个答案:

答案 0 :(得分:1)

不,即使基类构造函数受到保护,派生类'自动生成的默认构造函数仍然是公共的。

有两种方法(我可以想到)防止派生类B直接可实例化:

1。删除A类

中的默认构造函数

这可以通过提供一个带伪参数的构造函数来实现:

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

2。强制派生类的构造函数受到保护

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();