我有以下简单的c ++代码:
class X {
public :
int x ;
X(int val) : x(val) {cout<<"one arg\n" ;}
X(const X&xx) {cout<<"const copy constr\n" ; x = xx.x ;}
X(X&xx) {cout<<"non const copy constr\n" ; x = xx.x ;}
X(const X&&xx) {cout<<"const move constr\n" ; x = xx.x ;}
X(X&&xx) {cout<<"non const move constr\n" ; x = xx.x ;}
X operator +(X &ob) {
X xx(x+ob.x) ; cout<<"add\n" ; return xx ;
}
X operator=(const X &x) {cout<<"const assign\n" ;}
X operator=(X &x) {cout<<"non const assign\n" ;}
X operator=(const X &&x) {cout<<"const move assign\n" ;}
X operator=(X &&x) {cout<<"non const move assign\n" ;}
} ;
main() {
X x1(10), x2(x1) ;
cout<<"$$$$$$$$$$$$$$\n" ;
X x3 = x1+x2 ;//does not invoke move/copy constr ---> do not know why
cout<<"###########"<<x3.x<<endl ;
cout<<"$$$$$$$$$$$$$$\n" ;
vector<X> v ;
v.push_back(X(100)) ;//invokes move constr
}
通过哪个构造函数创建对象 x3 ?
答案 0 :(得分:4)
在stackoverflow上有这个问题的重复重复,移动/复制已被删除,请参阅http://en.wikipedia.org/wiki/Copy_elision
正如GCC FAQ("My copy constructor doesn't run!")中所述,当使用gcc(或clang)编译-fno-elide-constructors
来查看每个中间临时对象被复制或移动时,但没有理由这样做是因为它会使你的程序慢得多。
您正在观察的是X
内的operator+
是在为x3
保留的堆栈位置构建的,因此不需要复制或移动,因为{已在正确的位置构建具有正确值的{1}}。如果您打印出X
的地址和xx
的地址,您会看到它们是同一个对象。