最近我正在测试一些 C++ 的深奥和黑暗的角落,我对一个微妙的点感到困惑。我的测试其实很简单:
// problem 1
// no any constructor call, g++ acts as a function declaration to the (howmany())
// g++ turns (howmany()) into (howmany(*)())
howmany t(howmany());
// problem 2
// only one constructor call
howmany t = howmany();
我对上面一行的期望是;第一的howmany()
构造函数调用将产生一个临时对象,然后编译器将使用该临时对象与复制构造函数来实例化t。然而,编译器的输出确实让我困惑,因为输出仅显示一个构造函数调用。我的朋友向我提到了编译器按值传递优化,但我们对此并不确定。我想知道这里发生了什么?
问题 2 的输出如下。问题 1 完全超出了对象实例化的范围,因为编译器将其视为函数指针声明。
howmany()
~howmany()
我的测试课是:
class howmany {
public:
howmany() {
out << "howmany()" << endl;
}
howmany(int i) {
out << "howmany(i)" << endl;
}
howmany(const howmany& refhm) {
out << "howmany(howmany&)" << endl;
}
howmany& operator=(const howmany& refhm) {
out << "operator=" << endl;
}
~howmany() {
out << "~howmany()" << endl;
}
void print1() {
cout << "print1()" << endl;
}
void print2() {
cout << "print2()" << endl;
}
};
这是最麻烦的解析 http://en.wikipedia.org/wiki/Most_vexing_parse here:
howmany t( howmany() );
为了解决这个问题,您需要添加一组额外的括号:
howmany t( (howmany()) );
^ ^
clang
在这里非常有帮助并警告您:
warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
howmany t( howmany() );
^~~~~~~~~~~~~
main.cpp:31:12: note: add a pair of parentheses to declare a variable
howmany t( howmany() );
^
( )
解决此问题的另一种方法是使用C++11 统一初始化 http://en.wikipedia.org/wiki/C%2B%2B11#Uniform_initialization syntax:
howmany t{ howmany{} };
^ ^^ ^
Update
寻址部分2
您将其添加到问题中标准草案 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3485.pdf在某些情况下允许省略复制/移动构造。我们可以从节中看到这一点12.8
复制和移动类对象段落31其中说:
当满足某些条件时,允许实现省略类对象的复制/移动构造,即使为复制/移动操作选择的构造函数和/或对象的析构函数具有副作用。在这种情况下,实现将省略的复制/移动操作的源和目标视为引用同一对象的两种不同方式,并且该对象的销毁发生在这两个对象本来应该被删除的时间的较晚时间。未经优化就被破坏。122 这种复制/移动操作的省略(称为复制省略)在以下情况下是允许的
并包括以下项目符号:
当未绑定到引用(12.2)的临时类对象将被复制/移动到具有相同 cv-unqualified 类型的类对象时,可以通过将临时对象直接构造到目标中来省略复制/移动操作省略的复制/移动
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)