为什么单独的一个函数按值返回的语句也会调用移动构造函数?

哈利_蜘蛛侠 2015-11-28 05:15:55
比如下面的代码:

#include <iostream>
using namespace std;

class IntCell
{
public:
IntCell(int num = 0) :m_iNum(num)
{
cout << "\nInt-parameter constructor called.\n";
}
// Copy constructor
IntCell(const IntCell & rhs) :m_iNum(rhs.m_iNum)
{
cout << "\nThe copy constructor called.\n";
}
// Move constructor
IntCell(IntCell && rhs) :m_iNum(std::move(rhs.m_iNum))
{
cout << "\nThe move constructor called.\n";
}
private:
int m_iNum;
};

IntCell func1(int n)
{
IntCell temp{ n };
return temp;
}

IntCell func2(int n)
{
return IntCell(n);
}
void separation( )
{
cout << "\n------------------------------------------------------\n";
}

int main( )
{
int num = 12;
cout << "\nThe functions invoked by\nfunc1(num);\n";
func1(num);
separation( );
cout << "\nThe functions invoked by\nfunc2(num);\n";
func2(num);
separation();
}

为什么它的运行结果是这样的?

The functions invoked by
func1(num);

Int-parameter constructor called.

The move constructor called.

------------------------------------------------------

The functions invoked by
func2(num);

Int-parameter constructor called.

------------------------------------------------------

具体就是,一,为什么
func1(num);

要调用move constructor?另一个就是,为什么
func2(num);

没有调用move constructor?
...全文
183 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-11-30
  • 打赏
  • 举报
回复
哈利_蜘蛛侠 2015-11-28
  • 打赏
  • 举报
回复
引用 4 楼 lm_whales 的回复:
函数返回值传递的几种途径 寄存器 X86通常是累计器浮点数栈顶,或者一个附加指针参数,也可能这个指针传递到累加器 1)整型 累计器 16 Bits int:ax,long dx:ax 32Bits int eax,long long ,__int64 edx:eax 64Bits int64_t rax, 2)浮点类型 浮点寄存器堆栈栈顶 st 3)结构类型的比较复杂,甚至比较长的类型,传递返回值指针(可能是通过累加器)
好抽象啊,没想到这个问题这么复杂
paschen 版主 2015-11-28
  • 打赏
  • 举报
回复
我猜fun2可能是《深度探索C++对象模型》中所说的NRV(Named Return Value) 为了不进行复制,其实函数返回的对象是在函数外创建,用一个参数传进来函数
fefe82 2015-11-28
  • 打赏
  • 举报
回复
return 会使用 copy-initialize 初始化被返回的值,这里会有一个 copy/move construction 。 但是,在一定条件下 copy/move construction 的调用可以被省略(请搜索 copy ellision)。不过这个省略是可选的,各个编译器实现的程度也不同。 你的输出,就是第一个没有被省略了,第二个被省略了。 我用 gcc 测试,两个 move 都不存在。
lm_whales 2015-11-28
  • 打赏
  • 举报
回复
函数返回值传递的几种途径 寄存器 X86通常是累计器浮点数栈顶,或者一个附加指针参数,也可能这个指针传递到累加器 1)整型 累计器 16 Bits int:ax,long dx:ax 32Bits int eax,long long ,__int64 edx:eax 64Bits int64_t rax, 2)浮点类型 浮点寄存器堆栈栈顶 st 3)结构类型的比较复杂,甚至比较长的类型,传递返回值指针(可能是通过累加器)
lm_whales 2015-11-28
  • 打赏
  • 举报
回复
返回值优化,本来就是右值引用(移动构造函数)大展身手的地方 不过,由于出来较晚,很多编译器早就实现返回值优化了

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧