我有以下代码:
#include <iostream>
class foo_class {
std::string value;
public:
foo_class(const foo_class& v) : value{v.value} {
std::cout << "copy constructor" << std::endl;
}
foo_class(foo_class&& v) : value{std::move(v.value)} {
std::cout << "move constructor" << std::endl;
}
~foo_class() {
std::cout << "destructor" << std::endl;
}
foo_class(std::string v) : value{std::move(v)} {
std::cout << "type constructor" << std::endl;
}
};
struct Data {
foo_class a;
foo_class b;
};
int main() {
std::string c = "3";
Data x{c,c+"3"};
return 0;
}
重要,我用GCC和Clang(分别为4.8.2和3.4)和标志 -fno-elide-constructors 进行编译,所以我们不要&#39;复制/移动构造函数。
执行结果如下:
type constructor
move constructor
destructor
type constructor
move constructor
destructor
destructor
destructor
这意味着根本没有使用复制构造函数,即使它应该用于struct Data的构造函数的第一个参数。
接下来,如果我删除了复制构造函数,根据我的编译器,代码仍然合法,但根据我的理解应该是非法的,因为我没有强制转换为&amp;&amp; (使用std :: move)传递Data的构造函数的第一个参数。
我的问题很简单: 为什么会这样? 我错过了什么吗?
答案 0 :(得分:6)
因为
中构造了foo_class
个对象
Data x{c,c+"3"};
都是临时的。因此,他们调用 move 构造函数而不是 copy 构造函数。
type constructor // 1. Construct a temporary foo_class object out of string "c" for a
move constructor // 2. Move the temporary object created above to x.a
destructor // 3. Destruct the temporary foo_class object created in 1
type constructor // 4. Same as 1, but the object is for b, and the string "33"
move constructor // 5. Same as 2, moved to x.b
destructor // 6. Destruct the temporary foo_class object created in 4
destructor // 7. Destruct x.b
destructor // 8. Destruct x.a