回 帖 发 新 帖 刷新版面

主题:[讨论]关于move constructor的一个问题

[em1][em1][em1]
首先大侠们请看我写的一段实验代码: 
#include <iostream> 
using namespace std; 
struct A 

int* a; 
}; 

struct B 

B(): b(new int(0)) 
{ cout<<"ordinary constructor called"<<endl; } 

B(B&& bb) 

cout<<"Move copy constructor (B) called"<<endl; 
this->b = bb.b; 
bb.b = nullptr; 


B(A && aa) 

cout<<"Move copy constructor (A) called"<<endl; 
b = aa.a; 
aa.a = nullptr; 


B operator = (A && aa) 

cout<<"Move assignment operator called"<<endl; 
b = aa.a; 
aa.a = nullptr; 


int* b; 
}; 

B ReturnB(); //返回一个B的对象 
A ReturnA(); //返回一个A的对象 
void main() 

ReturnB(); 
B bb = ReturnA(); 
B cc = ReturnB(); 


B ReturnB() 

B bb; 
return bb; 


A ReturnA() 

A aa; 
return aa; 


我用VS2010编译执行后的输出结果是: 
ordinary constructor called 
Move copy constructor (A) called 
ordinary constructor called 
请按任意键继续. . . 

输出的第一句说明我调用ReturnB的时候会调用一次ordinary constructor, 
输出的第二句说明ReturnA返回值是一个右值, 
输出的第三句,显然是我调用ReturnB的时候输出的。 
那么,我的main函数里的第三句:B cc = ReturnB(); 调用了ReturnB()以后一定还要对cc进行初始化吧?可是,为什么没有任何输出?也就是说,为什么这一句没有调用我定义的任何一个constructor? 
求大侠们指点迷津[em2]

回复列表 (共3个回复)

沙发

和 右值引用 无关
根据RVO条例,直接被优化掉了。即,不需要 创建再移动,而是直接在目的地 创建
(BTW:代码不排版,命名方式等,看得令人不舒服)

板凳

哦,原来是这样啊,谢谢了[em2]
我写程序的时候是有排版的,后来复制了以后就没有缩进了
原本我写的程序很长的,然后简化成一个实验以后变量的命名就比较随意了[em8]
谢谢你的提醒,以后我会注意的

3 楼

我还想问一下,按照那个原则,是不是我写的这个成员函数是没有必要的?
B(B&& bb) 

    cout<<"Move copy constructor (B) called"<<endl; 
    this->b = bb.b; 
    bb.b = nullptr; 
}

我来回复

您尚未登录,请登录后再回复。点此登录或注册