c++ - 继承私有(private)构造函数

标签 c++ c++11 constructor

尝试在具有私有(private) ctor 的类上允许 make_unique 我遇到了以下两种情况之间的奇怪差异:


案例 1 - 空 ctor - 编译

class A {
    int _i;
    A(): _i(7) {}
public:
    template<typename... T>
    static std::unique_ptr<A> create(T&&... t) {
        struct enablePrivateCtor : public A {
            using A::A;
        };
        return std::make_unique<enablePrivateCtor>(std::forward<T>(t)...);
    }
    void doIt() const {
        std::cout << _i << std::endl;
    }
};

int main() {
    auto a = A::create();
    a->doIt();
}

输出:

7

情况 2 - 非空构造函数 - 不编译

class A {
    int _i;
    A(int i): _i(i) {} // <- change 1, ctor getting int
public:
    // no change here!
    template<typename... T>
    static std::unique_ptr<A> create(T&&... t) {
        struct enablePrivateCtor : public A {
            using A::A;
        };
        return std::make_unique<enablePrivateCtor>(std::forward<T>(t)...);
    }
    void doIt() const {
        std::cout << _i << std::endl;
    }
};

int main() {
    auto a = A::create(7); // <- change 2, sending 7
    a->doIt();
}

编译错误:

unique_ptr.h: error: calling a private constructor of class 'enablePrivateCtor'

为什么第一个 - 带有空 ctor - 可以,而第二个 - 非空 ctor - 不行?

最佳答案

默认构造函数永远不会被继承。因此,第一个enablePrivateCtor生成一个默认构造函数,调用基类默认构造函数。

当您继承构造函数时(如第二种情况),新构造函数与继承的构造函数具有相同的访问级别。因此,由于 A::A(int) 是私有(private)的,因此 enablePrivateCtor::enablePrivateCtor(int) 也是私有(private)的。因此,您将无法使用它进行构建。

如果您需要让私有(private)构造函数能够被间接调用(通过make_unique/emplace/等),那么您需要使用私钥类型。像这样:

class A;

class A_key
{
  A_key() = default;
  A_key(int) {} //Prevent `A_key` from being an aggregate.

  friend class A;
};

class A {
    int _i;
public:
    A(int i, A_key): _i(i) {}

    // no change here!
    template<typename... T>
    static std::unique_ptr<A> create(T&&... t)
    {
        return std::make_unique<A>(std::forward<T>(t)..., A_key{});
    }

    void doIt() const {
        std::cout << _i << std::endl;
    }
};

...

auto ptr = A::create(7);
A a(7, A_key{}); //Does not compile, since you're not a friend.

A_key 可公开复制,但不可公开默认构造。所以非私有(private)代码可以传递它们,但非私有(private)代码不能创建它们。

关于c++ - 继承私有(private)构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46157775/

相关文章:

c++ - QProcess 不显示命令窗口

c++ - 游戏/程序如何计算高于 C++ 限制的数字?

scala - Scala 中重写和继承的辅助构造函数

javascript - 构造函数可以返回什么值来避免返回 this?

c++ - MFC - 在 DLL 卸载时扫描我的代码以查找任何剩余的计时器、事件、线程等

c++ - VIM omnicppcomplete 对函数参数不起作用

C++ For 循环遍历结构 vector (包含更多结构 vector )

c++ - 减少 std::bind 模板代码膨胀?

javascript - 如何在 cef 框架中支持 window.external.xxx

c++ - 从其他容器构造的 STL 容器(例如,从 vector 列表)