Agr*_*hak 3 c++ destructor move c++11
我的理解是在调用move构造函数之后在输入上调用析构函数.我决定在代码中测试它(见底部),但得到的结果与我的预期不同.我使用std :: unique_ptr得到了相同的结果.
期望:
1
2
bar constructed
foo destructed //due to move
3
i'm foo
4
[Error?]
Run Code Online (Sandbox Code Playgroud)
实际:
1
2
bar constructed
3
i'm foo
4
i'm foo
5
foo destructed
foo destructed
Run Code Online (Sandbox Code Playgroud)
码:
#include <iostream>
class Foo
{
public:
~Foo()
{
std::cout << "foo deconstructed" << std::endl;
}
void speak()
{
std::cout << "i'm foo" << std::endl;
}
};
class Bar
{
public:
Bar(Foo&& foo) : foo_(foo)
{
std::cout << "bar constructed" << std::endl;
}
Foo foo_;
};
int main()
{
std::cout << "1" << std::endl;
Foo foo;
std::cout << "2" << std::endl;
Bar bar(std::move(foo));
std::cout << "3" << std::endl;
bar.foo_.speak();
std::cout << "4" << std::endl;
foo.speak();
std::cout << "5" << std::endl;
return 0;
Run Code Online (Sandbox Code Playgroud)
}
zmb*_*zmb 12
我的理解是在调用move构造函数之后在输入上调用析构函数
你的理解是不正确的.在调用析构函数时,没有关于移动语义或C++ 11的更改.这里没有任何改变 - main在这种情况下,foo的析构函数会被调用.
您的混淆可能源于这样一个事实:在许多情况下,似乎在移动构造函数之后立即调用析构函数.
例如,如果你要Bar使用rvalue 创建一个:Bar bar(Foo{});析构函数Foo将在Bar移动构造函数之后运行.这不是因为有一个移动构造函数 - 这是因为临时Foo对象的生命周期已经结束.
析构函数在其生命周期结束时被调用 - 对于自动存储持续时间对象,例如foo,当它们超出范围时会发生这种情况.对于静态存储持续时间对象,当程序退出时会发生这种情况.对于临时工,这种情况也会发生
Foo foo = Foo();,假设没有复制省略,则创建的临时文件Foo()被销毁.{const Foo& foo = Foo(); doStuff();}被破坏时--In,当范围结束时销毁临时(}).这些标准都与移动构造函数无关.虽然没有强制要求,但移动构造函数通常会将移出的对象保留为有效状态.