C++ 在移动构造期间,可以对从对象移动的基本类型成员的值说些什么?
考虑一下这个代码C++ 在移动构造期间,可以对从对象移动的基本类型成员的值说些什么?,c++,c++11,language-lawyer,move-semantics,C++,C++11,Language Lawyer,Move Semantics,考虑一下这个代码 Foo f1; Foo f2{ std::move(f1) }; 我希望f1的成员值不再一定包含默认构造函数给定的值。但是,使用Foo的这种实现对多个编译器进行测试表明情况并非如此 class Foo { public: Foo() = default; Foo(Foo &&) = default; std::string s{ "foo" }; bool t{ true }; bool f{ false }; };
Foo f1;
Foo f2{ std::move(f1) };
我希望
f1
的成员值不再一定包含默认构造函数给定的值。但是,使用Foo
的这种实现对多个编译器进行测试表明情况并非如此
class Foo
{
public:
Foo() = default;
Foo(Foo &&) = default;
std::string s{ "foo" };
bool t{ true };
bool f{ false };
};
移动后f1.t
始终为true
,f1.f
始终为false
。如中所述,我希望值不是不确定的,就是两个布尔值具有相同的值。但是,它们似乎获得了与从默认构造函数获得的值相同的值
这只是我的编译器的一个实现细节(巧合的是相同的)还是这在标准中
移动后f1.t
始终为true
,f1.f
始终为false
对于基本类型,移动就是复制。您不希望您的实现复制bool和将旧的值归零-这是不必要的额外工作。在一个简单的POD中,移动将只是一个memcpy
——但是如果你的建议会发生,那么你还必须执行memset
。什么都不做要快得多
这只是我的编译器的一个实现细节(巧合的是相同的),还是在标准中
这在以下标准中:
非联合类X的隐式定义的复制/移动赋值运算符执行成员复制-
/移动其子对象的指定。[…]每个子对象都按以下方式指定
适合其类型:-[…]
-如果子对象是标量类型,则使用内置赋值运算符
“我希望f1的成员值现在可以取消初始化”您不能取消已初始化的内容。您可以将未初始化的内容移动到其位置:不,这将是未定义的行为(从未初始化的变量读取)。但您的示例没有显示这一点。是的,可能我对此不确定。您的意思是:1)最后一行是未定义的行为,因为
initialized
未初始化。或者2)最后一行没有问题,因为已初始化
实际上已初始化?如果2)何时初始化为“”?否,仅初始化一次。移动构造函数利用了std::string
的移动构造函数,它将状态从initialized.state
中移除。这恰好是一个相当于“”的字符串`