【问题标题】:Instantiating objects without calling the constructor in C++ [duplicate]在不调用 C++ 中的构造函数的情况下实例化对象 [重复]
【发布时间】:2016-07-06 11:09:10
【问题描述】:

我是 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 条语句没有,我可以弄清楚原因。

你知道为什么第五条语句不调用类构造函数吗? 谢谢。

【问题讨论】:

  • 5 是一个函数原型,看最麻烦的解析。
  • 5 不创建 Dog 对象。
  • @sergej 您应该添加您的评论作为答案。 edit 太晚了; HolyBlackCat 打败了你。

标签: c++ constructor


【解决方案1】:

5 是 C++ 的most vexing parse 的一个示例。

Dog dog();

这声明了一个名为dog 的函数,它不接受任何参数并返回一个Dog。为了避免 令人烦恼的解析(如果您使用的是 C++11),您可以这样做:

Dog dog{};

并且在语义上(至少直到 C++17),Dog dog = Dog(); 将首先创建一个临时对象(Dog()),然后移动构造(或复制构造,如果Dog 类没有移动构造)命名对象(dog)。尽管编译器可能会优化迁移,但此语句的语义确实与其他语句不同。

如果我没记错的话,从 C++17 开始,P0135r0 将改变 Dog dog = Dog(); 的语义,使其与 Dog dog; 具有相同的含义。

编辑:正如@LightnessRacesinOrbit 在 cmets 中指出的那样,Dog dog(); 是令人烦恼的,但不是最令人烦恼的解析。 Dog dog(Dog()); 是真正最令人头疼的解析。 Dog dog(); 只是一个简单的声明,我猜。

【讨论】:

  • @LightnessRacesinOrbit 嗯,我可能弄错了。 任何可以被解析为函数声明的东西都将是——这不是最令人头疼的解析吗?
  • 不,这是语言的一个简单事实。它会导致最令人烦恼的解析(Dog dog(Dog()),根据您链接到的文章),但事实并非如此。我喜欢称其为“不那么麻烦的解析”作为一种折衷方案;)
【解决方案2】:
Dog dog();

此行不创建对象,它被解析为函数声明。

如果我没记错的话,它被称为最令人头疼的解析

【讨论】:

    猜你喜欢
    • 2010-09-15
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 2016-11-18
    • 2015-12-04
    相关资源
    最近更新 更多