我使用的是 Visual C++ 2010 (编译器版本16。x),我正在编译代码:使用代码> Cl/EHsc /W4测试。CPP < /代码>。在构建Foo_2的过程中,我希望看到对构造函数和析构函数的额外调用,以便创建临时对象,并调用赋值操作符,以便将临时对象赋值给Foo_2。有人能给我解释一下为什么不是这样吗。如果我在这里遗漏了一些非常明显的东西,我深表歉意。,c++,default-constructor,C++,Default Constructor" /> 我使用的是 Visual C++ 2010 (编译器版本16。x),我正在编译代码:使用代码> Cl/EHsc /W4测试。CPP < /代码>。在构建Foo_2的过程中,我希望看到对构造函数和析构函数的额外调用,以便创建临时对象,并调用赋值操作符,以便将临时对象赋值给Foo_2。有人能给我解释一下为什么不是这样吗。如果我在这里遗漏了一些非常明显的东西,我深表歉意。,c++,default-constructor,C++,Default Constructor" />

对象创建中涉及的构造函数和析构函数调用 我使用下面的代码片段比较两种在C++中创建对象的方法。 #include <iostream> using std::cout; using std::endl; class Foo { public: Foo() : x(0) { cout << "In Foo constructor." << endl; } ~Foo() { cout << "In Foo destructor." << endl; } Foo(const Foo&) { cout << "In Foo copy constructor." << endl; } // Assignment operator. Foo& operator=(const Foo&) { cout << "In assignment operator." << endl; return *this; } private: int x; }; int main() { cout << "Constructing Foo 1" << endl; Foo Foo_1; cout << "Constructing Foo 2" << endl; Foo Foo_2 = Foo(); return 0; } < >我使用的是 Visual C++ 2010 (编译器版本16。x),我正在编译代码:使用代码> Cl/EHsc /W4测试。CPP < /代码>。在构建Foo_2的过程中,我希望看到对构造函数和析构函数的额外调用,以便创建临时对象,并调用赋值操作符,以便将临时对象赋值给Foo_2。有人能给我解释一下为什么不是这样吗。如果我在这里遗漏了一些非常明显的东西,我深表歉意。

对象创建中涉及的构造函数和析构函数调用 我使用下面的代码片段比较两种在C++中创建对象的方法。 #include <iostream> using std::cout; using std::endl; class Foo { public: Foo() : x(0) { cout << "In Foo constructor." << endl; } ~Foo() { cout << "In Foo destructor." << endl; } Foo(const Foo&) { cout << "In Foo copy constructor." << endl; } // Assignment operator. Foo& operator=(const Foo&) { cout << "In assignment operator." << endl; return *this; } private: int x; }; int main() { cout << "Constructing Foo 1" << endl; Foo Foo_1; cout << "Constructing Foo 2" << endl; Foo Foo_2 = Foo(); return 0; } < >我使用的是 Visual C++ 2010 (编译器版本16。x),我正在编译代码:使用代码> Cl/EHsc /W4测试。CPP < /代码>。在构建Foo_2的过程中,我希望看到对构造函数和析构函数的额外调用,以便创建临时对象,并调用赋值操作符,以便将临时对象赋值给Foo_2。有人能给我解释一下为什么不是这样吗。如果我在这里遗漏了一些非常明显的东西,我深表歉意。,c++,default-constructor,C++,Default Constructor,Foo Foo_2=Foo()类似于Foo-Foo_2(Foo())。编译器足够聪明,可以做到这一点,没有调用赋值运算符。顺便说一句,赋值运算符中有一个错误-返回对对象的引用而不是复制它。有两种初始化形式可用于Foo: Foo f1; Foo f2 = Foo(); 第一个使用默认构造函数直接构造f。第二个使用默认构造函数构造类型为Foo的临时对象,并将该临时对象复制到f2中。后者就是你所描述的你所期望的。你是对的,除了一条额外的规则:如果这种形式的初始化是有效的(在这里;将复制构造函数设为私

Foo Foo_2=Foo()
类似于
Foo-Foo_2(Foo())。编译器足够聪明,可以做到这一点,没有调用赋值运算符。顺便说一句,赋值运算符中有一个错误-返回对对象的引用而不是复制它。

有两种初始化形式可用于
Foo

Foo f1;
Foo f2 = Foo();
第一个使用默认构造函数直接构造
f
。第二个使用默认构造函数构造类型为
Foo
的临时对象,并将该临时对象复制到
f2
中。后者就是你所描述的你所期望的。你是对的,除了一条额外的规则:如果这种形式的初始化是有效的(在这里;将复制构造函数设为私有,然后看看会发生什么),编译器可以“省略”复制构造并直接构造
f2
,就像在第一个版本中一样。这就是你看到的。编译器不需要省略复制构造函数,但我最近使用的每一个编译器都会这样做。

第一个“本周大师”问题就是关于您的问题
特别是编译器优化的注意事项

不,不是糖。将
Foo
的复制构造函数设为私有,然后再试一次。@Pete Becker-我的错,修复了回复
Foo-Foo_2(Foo())
没有解释为什么他的示例中只有两个构造函数而不是三个。嗨,Pete,非常感谢您的反馈。这就为我解释了。嗨,皮特,我试过让复制构造函数私有化的测试,但代码无法编译。它声明它无法访问私有成员Foo::Foo。我现在的问题是,如果它是复制构造,那么为什么我在输出中看不到“In Foo copy constructor”。嗨,抱歉,我想我从Sapien2的帖子中的链接看到了为什么我没有看到它。编译器会对其进行优化。引用链接:“在这种情况下,编译器实际上被允许(但不是必需的)优化复制构造。如果它确实优化了它,那么复制构造函数必须仍然是可访问的。”你上面也这么说。@Francis-对。编译器可以跳过复制构造函数,但前提是它可用。因此,将其设置为私有将使副本构造无效,而省略副本构造函数也将无效。感谢链接。这也很有帮助。我应该在问之前多搜索一下!!
Foo f1;
Foo f2 = Foo();