初学C++的一点疑问,移动复制构造的
自己编的代码#include<iostream>usingstd::cin;usingstd::cout;usingstd::endl;usingstd::move;cl...
自己编的代码
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::move;
class strmy
{
public:
char* str;
int len;
strmy(char* strp="John")
{
cout<<"Constructor Called"<<endl;
str=new char[strlen(strp)+1];
strcpy_s(str,strlen(strp)+1,strp);
len=strlen(str);
}
strmy(strmy& strmy1)
{
cout<<"copy constructor called"<<endl;
char* str=new char[strlen(strmy1.str)+1];
strcpy_s(str,strlen(strmy1.str)+1,strmy1.str);
len=strlen(str);
}
strmy(strmy&& strmy1)
{
cout<<"Move constructor called"<<endl;
char* str=strmy1.str;
strmy1.str=nullptr;
}
strmy returnrvalue()
{
strmy ex("Mary Smith");
return ex;
}
strmy& operator=(strmy&& strmy1)
{
cout<<"Move assignment constructor called."<<endl;
delete[] str;
str=strmy1.str;
strmy1.str=nullptr;
return *this;
}
~strmy()
{
cout<<"destructor called"<<endl;
delete[] str;
}
};
int main()
{
strmy str;
strmy str1(str.returnrvalue());
}
问题在于这个str.returnrvalue返回的是右值,为啥strmy str1(str.returnrvalue)调用的是复制构造,而不是移动复制构造呢? 展开
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::move;
class strmy
{
public:
char* str;
int len;
strmy(char* strp="John")
{
cout<<"Constructor Called"<<endl;
str=new char[strlen(strp)+1];
strcpy_s(str,strlen(strp)+1,strp);
len=strlen(str);
}
strmy(strmy& strmy1)
{
cout<<"copy constructor called"<<endl;
char* str=new char[strlen(strmy1.str)+1];
strcpy_s(str,strlen(strmy1.str)+1,strmy1.str);
len=strlen(str);
}
strmy(strmy&& strmy1)
{
cout<<"Move constructor called"<<endl;
char* str=strmy1.str;
strmy1.str=nullptr;
}
strmy returnrvalue()
{
strmy ex("Mary Smith");
return ex;
}
strmy& operator=(strmy&& strmy1)
{
cout<<"Move assignment constructor called."<<endl;
delete[] str;
str=strmy1.str;
strmy1.str=nullptr;
return *this;
}
~strmy()
{
cout<<"destructor called"<<endl;
delete[] str;
}
};
int main()
{
strmy str;
strmy str1(str.returnrvalue());
}
问题在于这个str.returnrvalue返回的是右值,为啥strmy str1(str.returnrvalue)调用的是复制构造,而不是移动复制构造呢? 展开
2个回答
展开全部
同学,你的编译器优化蠢亩关掉了吗?一些高级编译器会对返回值进行优化。C++11的右值引用是从语法层面上对代码进行优化,实际上现在的编译器已经能自动执行多种优化。
对于用返回值初始化宽档局对象的做法,有的编译器可以直接使用局部变量对新对象进行拷贝构造,所以中间过程慎让就没有临时变量的存在。
对于用返回值初始化宽档局对象的做法,有的编译器可以直接使用局部变量对新对象进行拷贝构造,所以中间过程慎让就没有临时变量的存在。
追问
请问这个优化该怎么关掉呢?我想试一下,我就想不明白,没有临时变量的产生,直接移动拷贝得了
追答
GCC编译器有一条编译选项可以关闭返回值优化,VC的把优化级别调低一点。具体的自信百度。
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
编译器太乎正源愚蠢了,清银无法判断出str.returnrvalue返回的是右值,换个机智点的编译器(如g++或clang)就可以调用移动构造函数了。
不过话又说回来,岁态机智的编译器会干脆把ex的构造和析构完全优化(删除)掉,并且提示出代码中十几处不合标准的地方……
不过话又说回来,岁态机智的编译器会干脆把ex的构造和析构完全优化(删除)掉,并且提示出代码中十几处不合标准的地方……
追问
恩,我知道,就是直接用局部对象ex去构造str1,省掉了临时对象,我用的是visual studio 2012,这个到底是不是编译器的问题?还是某个重点我没把握住?
追答
编译器的问题,VS本身做的就比g++和clang差一点,不过本来就不应该依赖这种东西的结果(这里是C++标准唯一一处“可以调用构造函数,也可以不调用,不管怎样,程序都是正确的”的地方)
g++和clang对于这段代码(删去无关的字符串操作)结果都是
Constructor Called
Constructor Called
destructor called
destructor called
假如用-fno-elide-constructors参数手动禁止掉省略临时对象的优化,g++和clang都会调用两次移动构造函数,不会调用复制构造函数
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询