我是C ++的新手,我目前正在学习构造函数。假设我有一个带有构造函数的类Dog:
class Dog{
Dog(){
std::cout << "Constructor called!
}
};
我知道在C ++中有不同的方式(如果我没有弄错的话)我们可以创建一个对象,例如:
1- Dog dog;
2- Dog dog = Dog();
3- Dog *dog = new Dog;
4- Dog *dog = new Dog();
5- Dog dog();
但是事情就是这样:1到4的语句都会调用构造函数,但是语句号5并不能解决原因。
你知道为什么第五个语句没有调用类构造函数吗? 感谢。
答案 0 :(得分:5)
5是C ++的most vexing parse。
Dog dog();
这声明了一个名为dog
的函数,它不接受任何参数并返回Dog
。要避免 most 烦恼的解析(如果你使用的是C ++ 11),你可以这样做:
Dog dog{};
在语义上(至少在C ++ 17之前),Dog dog = Dog();
将首先创建一个临时对象(Dog()
),然后移动构造(或复制构造,如果Dog
类没有移动构造函数)来自它的命名对象(dog
)。虽然编译器可能会优化移动,但这个语句确实与其他语句有不同的语义。
如果我没记错的话,自C ++ 17起,P0135r0将改变Dog dog = Dog();
的语义,使其与Dog dog;
具有相同的含义。
编辑:正如@LightnessRacesinOrbit在评论中指出的那样,Dog dog();
令人烦恼,但并不是最令人头疼的解析。 Dog dog(Dog());
是最令人烦恼的解析。我想,Dog dog();
只是一个简单明了的宣言。
答案 1 :(得分:2)
Dog dog();
这一行不会创建一个对象,它被解析为一个函数声明。
如果我没记错的话,它被称为最烦恼的解析。