c++ - 父级上 protected 构造函数和继承的默认构造函数不 protected

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

当父类受到保护时,我有一个关于继承类上的默认构造函数的问题,在我看来,子类也将有一个默认构造函数受到保护,但事实并非如此。

有没有办法强制保护默认构造函数,而不是将其强制作用于子类?

C++11 - gcc 版本 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;
}

感谢您的帮助,

Wcdr

最佳答案

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

有两种方法(我能想到的)来防止派生类 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 工厂函数的人都会理解为什么构造函数被设为私有(private)或 protected 。


编辑

在类层次结构中使用静态 create 工厂函数时,常见的习惯用法是派生类也提供静态 create 工厂函数,并将其构造函数设为私有(private)或 protected .

派生类不应使用基类的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();

关于c++ - 父级上 protected 构造函数和继承的默认构造函数不 protected ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34577563/

相关文章:

c++ - 类中成员函数模板的显式实例化

c++ - 如何将整数传递给 CreateThread()?

c++ - “stoi”未在此范围内声明

c++ - 如何从可变元组中获取元素?

java - 向现有对象添加新属性

inheritance - 为什么这个类被认为是最终的?

c++ - 为仅包含标题的库创建 block

C++ DLL 函数导出。 DLL 不会保持加载状态

c++ - "static initialization"到底是什么意思?

c++ - 继承、隐藏函数和作用域 c++