c++ move赋值首先触发move构造函数
C++ move assignment triggers move constructor first
#include <iostream>
class C {
public:
~C() { std::cout << this << " destructorn"; }
C() { std::cout << this << " constructorn"; }
C(C&& rhs) {
std::cout << &rhs << " rhsn";
std::cout << this << " move constructorn";
}
C& operator=(C&& rhs) {
std::cout << &rhs << " rhsn";
std::cout << this << " move assignmentn";
return *this;
}
};
C make_one() {
C tmp;
return tmp;
}
int main() {
std::cout << "move constructor:n";
C c1(make_one());
std::cout << &c1 << " &c1nn";
std::cout << "move assignment:n";
C c2;
c2 = make_one();
...
}
输出:move constructor:
000000000021F9B4 constructor // tmp constructed in make_one()
000000000021F9B4 rhs // return triggers tmp being passed to ...
000000000021FA04 move constructor // ... c1's move constructor (see below)
000000000021F9B4 destructor // tmp destructs on going out of scope
000000000021FA04 &c1 // (confirmed c1's address)
move assignment:
000000000021FA24 constructor // c2 constructed
000000000021F9B4 constructor // tmp constructed in make_one() again
000000000021F9B4 rhs // tmp passed to ...
000000000021FA34 move constructor // ... a new object's move constructor
000000000021F9B4 destructor // tmp destructs on going out of scope
000000000021FA34 rhs // new object passed to ...
000000000021FA24 move assignment // .. c2's move assignment operator
000000000021FA34 destructor // new object destructs
...
move赋值似乎首先触发move构造函数并创建一个额外的对象。这正常吗?我希望(通过类比复制赋值)tmp直接传递给c2的move赋值。
[Visual Studio Express 2013]
这个"额外对象"叫做返回值。当从函数返回值时;这个值是从您提供给return
语句的值构造的copy/move。
通常会经历copy省略,这可能解释了为什么你没有认出它。当复制省略发生时,C tmp;
行实际上会直接将tmp
构造成返回值。复制省略也可能发生在其他一些情况下;有关全文,请参阅c++ 11 [class.copy]#31。
假设您在这里手动禁用了复制省略,或者编译器认为不执行复制省略是一个好主意。更新:你的编译器只在发布版本上做这种特殊的复制省略-感谢Praetorian
我已经完成了我的例子,把它留在这里,以防它对其他人有帮助。
#include <iostream>
class C {
public:
~C() { std::cout << this << " destructorn"; }
C() { std::cout << this << " constructorn"; }
C(const C& rhs) {
std::cout << &rhs << " rhsn";
std::cout << this << " copy constructorn";
}
C& operator=(const C& rhs) {
std::cout << &rhs << " rhsn";
std::cout << this << " copy assignmentn";
return *this;
}
C(C&& rhs) {
std::cout << &rhs << " rhsn";
std::cout << this << " move constructorn";
}
C& operator=(C&& rhs) {
std::cout << &rhs << " rhsn";
std::cout << this << " move assignmentn";
return *this;
}
};
C make_one() {
C tmp;
return tmp;
}
int main() {
std::cout << "c1's constructor:n";
C c1;
std::cout << "nc1 passed to c2's copy constructor:n";
C c2(c1);
std::cout << &c2 << " &c2nn";
std::cout << "c3 and c4's constructors:n";
C c3, c4;
std::cout << "c3 passed to c4's copy assignment:n";
c4 = c3;
std::cout << "ntmp constructed, passed to c5's move constructor then destructedn";
C c5(make_one());
std::cout << &c5 << " &c5nn";
std::cout << "c6's constructor:n";
C c6;
std::cout << "tmp constructed, passed to return value's move constructor then destructedn"
"return value passed to c6's move assignment then destructed:n";
c6 = make_one();
return 0;
}
调试输出:c1's constructor:
000000000013F9B4 constructor
c1 passed to c2's copy constructor:
000000000013F9B4 rhs
000000000013F9D4 constructor
000000000013F9D4 &c2
c3 and c4's constructors:
000000000013F9F4 constructor
000000000013FA14 constructor
c3 passed to c4's copy assignment:
000000000013F9F4 rhs
000000000013FA14 copy assignment
tmp constructed, passed to c5's move constructor then destructed
000000000013F964 constructor
000000000013F964 rhs
000000000013FA34 move constructor
000000000013F964 destructor
000000000013FA34 &c5
c6's constructor:
000000000013FA54 constructor
tmp constructed, passed to return value's move constructor then destructed
return value passed to c6's move assignment then destructed:
000000000013F964 constructor
000000000013F964 rhs
000000000013FA64 move constructor
000000000013F964 destructor
000000000013FA64 rhs
000000000013FA54 move assignment
000000000013FA64 destructor
...
释放输出(显示move构造函数的省略):
c1's constructor:
00000000001BFC41 constructor
c1 passed to c2's copy constructor:
00000000001BFC41 rhs
00000000001BFC40 constructor
00000000001BFC40 &c2
c3 and c4's constructors:
00000000001BFC78 constructor
00000000001BFC70 constructor
c3 passed to c4's copy assignment:
00000000001BFC78 rhs
00000000001BFC70 copy assignment
tmp constructed, passed to c5's move constructor then destructed
00000000001BFC68 constructor
00000000001BFC68 &c5
c6's constructor:
00000000001BFC60 constructor
tmp constructed, passed to return value's move constructor then destructed
return value passed to c6's move assignment then destructed:
00000000001BFC42 constructor
00000000001BFC42 rhs
00000000001BFC60 move assignment
00000000001BFC42 destructor
....
相关文章:
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 添加自定义析构函数时,Move 构造函数在派生类中消失
- std::映射,只有move构造函数可用
- 为什么我的代码中没有调用move构造函数
- std::转换move构造函数的模板专业化的变体
- 如何调用move构造函数
- 我可以将 std::move 与不提供 move 构造函数的类一起使用吗?
- 为什么noexcept move构造函数在向量重新分配期间没有被调用
- 为什么在声明析构函数时必须声明 copy & move 构造函数?
- 如何在我自己的类 Vector 中使用 Move 构造函数而不是 Move 赋值运算符
- GoogleTest Move 构造函数覆盖率
- C - 构造函数,复制构造函数,MOVE构造函数,驱动器
- 如何在基类中调用 "move" '&&' 构造函数?在C++
- 如果我有一个向量(或类似的东西)成员变量,那么move构造函数看起来怎么样
- std::vector的move构造函数是否调用项的move构造器
- 为什么我们需要在move构造函数中将右值引用设置为null
- move构造函数在C++中调用了两次吗
- 实现move构造函数如何影响返回值优化
- 不能默认使用Move构造函数
- C++合成的move构造函数如何受到volatile和虚拟成员的影响