在不调用C ++中的构造函数的情况下实例化对象

时间:2016-07-06 11:09:10

标签: c++ constructor

我是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并不能解决原因。

你知道为什么第五个语句没有调用类构造函数吗? 感谢。

2 个答案:

答案 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();

这一行不会创建一个对象,它被解析为一个函数声明。

如果我没记错的话,它被称为最烦恼的解析