【问题标题】:Default argument allowing constructor to call private method默认参数允许构造函数调用私有方法
【发布时间】:2018-03-11 11:53:16
【问题描述】:

我有课

class A
{
public:
    class Key
    {
        Key() {}
        Key(Key const &) {}
    };

    A(Key key, int a = 5) {}
};

Key 的构造函数是私有的,所以没有人应该能够构造对象A。但是,使用以下代码:

int main() {
    A a(A::Key()); // this compiles !!!
    A a2(A::Key(), 5); // this doesn't
    // somehow defaulting the argument causes the private constructor
    // to be OK - no idea why
    return 0;
}

通过在我的构造函数中使用int a 的默认参数,编译器很高兴地编译了我对A::Key() 的使用,尽管它是私有的。但是,如果我明确地为 a 赋值,编译器会正确识别出我正在尝试使用私有构造函数并出错。为什么是这样?是否有办法强制编译器在第一个示例中也出错?

请参阅here 以获取实时示例。

【问题讨论】:

    标签: c++ constructor private most-vexing-parse


    【解决方案1】:

    这是因为最麻烦的解析。

    A a(A::Key());
    

    不创建名为aA 并使用临时A::Key 构造它。它创建了一个函数a,它返回一个A,并采用一个未命名的指针指向返回一个A::Key的函数。

    如果你添加一对括号,你会得到一个编译器错误

    A a((A::Key()));
    

    您正在尝试调用私有构造函数。或者,您可以使用统一初始化,这也可以消除歧义并导致编译错误

    A a(A::Key{});
    

    【讨论】:

    • 我知道我以前在某个地方见过这个......我每 5 年遇到一次并且因为我很久没见过它而感到困惑的事情之一......谢谢帮助。
    • @R_Kapp 没问题,很乐意提供帮助。
    猜你喜欢
    • 1970-01-01
    • 2018-11-25
    • 1970-01-01
    • 2011-05-26
    • 2011-09-12
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多