
Complex c{ Complex{1, 2} }; 为什么这条语句不会进入移动构造函数呢?
用 g++,关闭了优化 g++ -O0 main.cpp
用 visual studio 2017,也关闭了优化
#include<iostream> using std::cout; using std::endl; class Cmplex { public: Complex(double real, double image) : _real(real), _image(image) {} Complex(const Complex& right); Complex(Complex&& right); Complex& operator=(const Complex& right); Complex& operator=(Complex&& right); virtual ~Complex(); private: double _real {}; double _image {}; }; Complex::Complex(const Complex& right) { cout << "&" << endl; _real = right._real; _image = right._image; } Complex::Complex(Complex&& right) { cout << "&&" << endl; _real = right._real; _image = right._image; } Complex& Complex::operator= (const Complex& right) { cout << "= &" << endl; if (this != &right) { _real = right._real; _image = right._image; } return *this; } Complex& Complex::operator= (Complex&& right) { cout << "= &&" << endl; if (this != &right) { _real = right._real; _image = right._image; } return *this; } Complex::~Complex() { cout << "des" << endl; } int main() { Complex c{ Complex{1, 2} }; //Complex c {std::move(Complex{1, 2})}; cout << &c << endl; return 0; } 1 edimetia3d 2021-05-02 13:50:21 +08:00 没必要关注这种 case, 八成是编译器把初始化优化了. |
2 leimao 2021-05-02 13:54:41 +08:00 当 argument 是 lvalue 的时候,invoke copy constructor; 当 argument 是 rvalue 的时候,invoke move constructor;。 https://leimao.github.io/blog/CPP-lvalue-rvalue-Reference/ |
3 leimao 2021-05-02 14:00:04 +08:00 确切的说应该叫 lvalue reference 和 rvalue reference 。 |
4 wisefree OP @edimetia3d 我也感觉是被优化了,所以关闭了优化,但是没有应有的效果。有其他的思路么? |
6 leimao 2021-05-02 14:14:02 +08:00 @wisefree 我想你问的应该是为什么 Complex c{ Complex{1, 2} };没有 invoke copy constructor ? |
7 leimao 2021-05-02 14:37:42 +08:00 @leimao 我跑了一下程序看了下结果想了想,一楼应该是对的。估计编译器把 ``` Complex c{ Complex{1, 2} }; ``` 优化成了 ``` Complex c{ 1, 2 }; ``` 所以你啥也没 print 出来。 |
8 leimao 2021-05-02 14:46:15 +08:00 @wisefree 个人想法: 碰到你这种奇怪的没必要的 construction 的方式,`Complex c{ Complex{1, 2} };`,编译器必须把你的语法“优化”(改)成以下两种之一。 1. `Complex c{1, 2};` 2. `Complex c_temp{1, 2}; Complex c{c_temp}; ` 不然你这个程序没法运行。 至于“优化”成 1 还是 2, 可能得看写编译器的人怎么写了。当然估计 100%的人会写 1, 因为 2 这个临时变量是完全没有必要的,浪费资源和 performance 。 |
9 lcdtyph 2021-05-02 15:08:49 +08:00 你需要关闭 constructor elision g++ -fno-elide-constructors --std=c++11 .... 在 c++17 之后你例子里的代码会被 guaranteed copy elision 保证干掉,所以就算加了这个参数也没用,因为已经不是优化而是标准之一了。在此之前都是编译器自己的 constructor elision 在作用。 |
10 lcdtyph 2021-05-02 15:11:26 +08:00 msvc 我不会用,不知道对应的选项是什么- - |
11 qieqie 2021-05-02 15:42:08 +08:00 copy elision |
15 jones2000 2021-05-03 19:01:08 +08:00 你这个要完成什么功能? 用最简单的语法完成你想要功能不就可以了. 怎么高深的语法, 有几个人会用呀? |
16 shrikextl 2021-06-14 20:28:39 +08:00 纠结这个干啥,移动构造又不是给你做这种构造写法的,想测试移动构造函数的方法多的很 |