【发布时间】:2014-03-13 02:07:24
【问题描述】:
我是 c++11 的新手,写了以下代码来了解 std::move 的工作原理:
#include <queue>
#include <stdio.h>
class X {
public:
X(int x) : x_(x) {}
~X() {
printf("X(%d) has be released.\n", x_);
}
X(X&&) = default;
X& operator = (X&&) = default;
X(const X&) = delete;
X& operator = (const X&) = delete;
private:
int x_;
};
int main() {
std::queue<X> xqueue;
for (int x = 0; x < 5; ++x) {
xqueue.push(std::move(X(x)));
}
return 0;
}
但是,它会生成以下输出,这表明每个X(n) 的析构函数都被调用了两次:
X(0) has be released.
X(1) has be released.
X(2) has be released.
X(3) has be released.
X(4) has be released.
X(0) has be released.
X(1) has be released.
X(2) has be released.
X(3) has be released.
X(4) has be released.
我可以想象第二轮输出发生在 main() 函数的末尾,而第一轮可能发生在循环中,当那些中间 Xs 超出范围时。
但是,我认为这样的中间Xs 的所有权将被完美地转移到队列中,并且在所有权转移期间不应调用它们的析构函数。
所以我的问题是:
- 当我看到一个实例被释放两次时,这是否意味着它执行的是复制而不是移动?
- 如果上面的答案是肯定的,那我怎样才能真正避免抄袭呢?
谢谢,
【问题讨论】:
标签: c++ c++11 destructor move