不允许在C ++中使用默认构造函数

时间:2017-12-01 20:12:44

标签: c++ c++11

我试图用C ++创建一个禁止使用默认构造函数的类。
然而,我认为我失败了,或者我不了解幕后发生的事情。以下是我到目前为止的情况:

class Point {
public:
        float x;
        float y;
        Point(float newX, float newY); //Definition is irrelevant
        Point() = delete; //Default or "empty" constructor is forbidden, so deleted
}
/* ... */
int main(void)
{
        Point a(1, 2); //Ok, should be available
        Point b; //Ok, does not compile
        Point c(); //Not ok, it does compile :(
}

我的预期行为是c点不编译。我非常感谢帮助产生这种行为,或者如果不可能的话,我会理解为什么会这样做。

提前谢谢

3 个答案:

答案 0 :(得分:8)

正在发生的是一个令人烦恼的解析。您没有声明一个对象,而是一个名为c且返回类型为Point的函数。

声明任何构造函数都会阻止编译器生成默认构造函数,因此=delete的声明是超级流。

聚合初始化

如果你知道订单,你甚至不需要构造函数:

Point p{newX, newY};

工作得很好。

统一初始化语法

将来,要避免此类情况,请使用{}

Point p{}; //default constructs

答案 1 :(得分:2)

该行

    Point c(); //Not ok, it does compile :(

不解释为创建Point类型的对象c,它被解释为声明一个返回Point并且不带参数的新函数c。看这里: https://en.wikipedia.org/wiki/Most_vexing_parse

也不需要这一行:

    Point() = delete; //Default or "empty" constructor is forbidden, so deleted

如果声明任何构造函数,则会覆盖默认构造函数。

答案 2 :(得分:1)

它确实编译,但只是因为它不是你认为的那样。您正确删除了默认构造函数。实际上已经声明一个非默认构造函数会阻止该类成为默认构造:

struct Foo {
    Foo(int);
}

Foo x; // wont compile

将默认构造函数声明为已删除是很好的做法,因为它明确指出默认构造函数是故意遗漏的。

为什么要编译?

Foo x();

声明一个返回Foo的函数。这被认为是最令人烦恼的解析。