我试图用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点不编译。我非常感谢帮助产生这种行为,或者如果不可能的话,我会理解为什么会这样做。
提前谢谢
答案 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
的函数。这被认为是最令人烦恼的解析。