【问题标题】:Protected constructor on parent and inherited default one not protected父级受保护的构造函数和继承的默认构造函数不受保护
【发布时间】:2016-04-07 06:19:39
【问题描述】:

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

除了在子类上强制默认构造函数之外,还有其他方法可以强制保护默认构造函数吗?

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

【问题讨论】:

  • 没有。基类通常不能“强制”派生类做任何事情。
  • @WCdr 你真的是想问是否有办法阻止 B 直接实例化?

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


【解决方案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();

【讨论】:

    猜你喜欢
    • 2013-08-01
    • 2010-09-17
    • 2019-08-24
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 2017-03-11
    • 1970-01-01
    • 2021-10-05
    相关资源
    最近更新 更多