gpt4 book ai didi

c++ - move 的对象仍然被破坏?

转载 作者:可可西里 更新时间:2023-11-01 18:27:56 24 4
gpt4 key购买 nike

在学习 C++11 时,我对 move 对象的行为方式感到惊讶。考虑这段代码:

#include <exception>
#include <iostream>
#include <type_traits>

class Moveable {
public:
Moveable() {
std::cout << "Acquire odd resource\n";
}

~Moveable() noexcept(false) {
std::cout << "Release odd resource\n";
// if (!std::uncaught_exception() && error_during_release) {
// throw std::exception("error");
// }
}

Moveable(Moveable const &) = delete;
Moveable &operator=(Moveable const &) = delete;

Moveable(Moveable &&) = default;
Moveable &operator=(Moveable &&) = default;
};

int main(int argc, char *argv[]) {
static_assert(!std::is_copy_constructible<Moveable>::value,
"is not copy constructible");
static_assert(!std::is_copy_assignable<Moveable>::value, "is not copy assignable");
static_assert(std::is_move_constructible<Moveable>::value, "is move constructible");
static_assert(std::is_move_assignable<Moveable>::value, "is move assignable");

Moveable moveable{};
Moveable moved{std::move(moveable)};
Moveable moved_again{std::move(moved)};
}

它产生这个输出:

$ clang++ --version
clang version 3.8.0 (tags/RELEASE_380/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/clang+llvm-3.8.0-x86_64-linux-gnu-ubuntu-14.04/bin
$ clang++ --std=c++14 --stdlib=libc++ -Wall -Werror -o move_and_destroy move_and_destroy.cc && ./move_and_destroy
Acquire odd resource
Release odd resource
Release odd resource
Release odd resource

我很惊讶,因为我希望创造一个可 move 的 RAII类型。然而,似乎每个 move 的中间体都被破坏了!

是否有一些变体允许我在“对象的生命周期”结束时释放我的资源一次? (也就是说,在 move 对象序列的生命周期结束时?)

处于类似情况的人可能应该使用 std::unique_ptr 并完成。然而,在这种情况下,~Moveable() 可能会抛出异常,显然 std::unique_ptr 的析构函数将在出现异常时终止程序(至少,在 clang 中3.8.0.)

最佳答案

是的,移出的对象被破坏了。它们仍处于未确定但有效的状态。它们仍然是对象。

如果您还记得 C++ 实际上并没有 move 任何东西,那将是最好的。 std::move 只是给你一个右值。所谓的“move 构造函数”只是复制构造函数的方便替代品,当您有右值时在查找过程中发现,并允许有机会交换类的封装数据而不是实际复制它。但是 C++ 不会为您 move 任何东西,并且它无法判断您何时进行了一些 move 。

因此,对于 C++ 来说,如果我们甚至可以决定这通常意味着什么,以某种方式阻止“移出”的对象,那么对于 C++ 来说,这将是不可行的危险和不切实际的,以防止以后进行销毁。使这种销毁对于您的移出对象是安全的(理想情况下是无操作)(例如,通过在您的 move 构造函数中将源指针设置为 nullptr),您会没事的。

关于c++ - move 的对象仍然被破坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38287425/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com