【发布时间】:2018-01-07 14:19:54
【问题描述】:
我为理解移动 CTOR 行为而编写的以下代码 sn-p 让我很难理解它的输出:
#include <iostream>
class Temp
{
public:
Temp(){
std::cout << "Temp DEFAULT CTOR called" << std::endl;
mp_Val = nullptr;
}
Temp(int inp) {
std::cout << "Temp CTOR called" << std::endl;
mp_Val = new int(inp);
}
Temp(const Temp& inp) {
std::cout << "Temp COPY CTOR called" << std::endl;
mp_Val = new int(*inp.mp_Val);
}
Temp& operator= (const Temp& inp) {
std::cout << "Temp ASSIGNMENT OPER called" << std::endl;
mp_Val = new int(*inp.mp_Val);
return *this;
}
int* mp_Val;
};
class B
{
public:
B(){
std::cout << "Class B DEFAULT CTOR" << std::endl;
mp_Val = nullptr;
}
B(int inp) {
std::cout << "Class B CTOR" << std::endl;
mp_Val = new Temp(inp);
}
B(const B& in) {
std::cout << "Class B COPY CTOR" << std::endl;
mp_Val = in.mp_Val;
}
B(B&& in){
std::cout << "Class B MOVE CTOR" << std::endl; //Doubt: 1
}
Temp *mp_Val;
};
int main() {
B obj1(200);
B obj2 = std::move(obj1);
auto temp = obj1.mp_Val;
std::cout << "Obj1 B::Temp address: " << obj1.mp_Val << std::endl;
std::cout << "Obj2 B::Temp address: " << obj2.mp_Val << std::endl; //Doubt: 2
return 0;
}
输出:
Class B CTOR
Temp CTOR called
Class B MOVE CTOR
Obj1 B::Temp address: 0xd48030
Obj2 B::Temp address: 0x400880
GCC 版本:4.6.3
我的问题是关于标记为Doubt 2的行。地址不应该打印为0吗?据我了解,由于我在class B 中定义了一个空移动CTOR(标记为Doubt 1),它应该调用Temp 类的默认CTOR(从日志中可以看出它没有调用)来初始化它的成员Temp 类型的变量 mp_Val。
显然我缺少一些东西。
【问题讨论】:
-
在 obj1 上移动之后,obj1 死了。然而您的代码仍在使用它。
-
@Eljay 这不是移动构造函数在 C++ 中的工作方式。
-
@Eljay 移动后
obj1处于与之前完全相同的状态,因为移动 ctor 不会以任何方式修改其参数。 -
@Eljay obj1 还没有死,因为我在移动 CTOR 中没有做任何事情。
-
"应该调用类
Temp"的默认CTOR"不,它不应该,因为mp_val是一个指针。如果mp_val是Temp类型的成员变量,它会这样。
标签: c++ c++11 move move-semantics move-constructor