我无法完全理解unique_ptr的赋值运算符。我了解,由于复制构造函数和赋值运算符被删除,我们只能移动它们,但是如果 一个已经包含分配的unique_ptr被移动操作覆盖吗?先前存储在智能指针中的内容是否已释放?
#include <iostream>
#include <memory>
class A{
public:
A() = default;
virtual void act() const {
std::cout << "act from A" << std::endl;
}
virtual ~A() {
std::cout << "destroyed A" << std::endl;
}
};
class B : public A {
public:
B() : A{} {}
void act() const override {
std::cout << "act from B" << std::endl;
}
~B() override {
std::cout << "destroyed from B " << std::endl;
}
};
int main() {
auto pP{std::make_unique<A>()};
pP->act();
==================== ! =======================
pP = std::make_unique<B>(); // || std::move(std::make_unique<B>())
==================== ! =======================
pP->act();
return 0;
}
当我这样做
pP = std::make_unique<B>();
这是否意味着在第一行分配给pP(新A())的内容会被自动破坏? 还是我应该选择:
pP.reset();
pP = std::make_unique<B>();
答案 0 :(得分:4)
是的,请参见C++11 draft standard的第20.9.1节第4段
另外,您可以根据请求将所有权转移到另一个唯一指针u2。完成后 进行这样的转移时,必须满足以下条件:
- u2.p等于转移前的u.p,
- u.p等于nullptr,并且
- 如果转移前u.d保持状态,则该状态已转移到u2.d。
与重置一样, u2必须通过预转移正确处置其预转移拥有的对象 所有权转移完成之前,关联的删除程序
换句话说,它会按照您的期望自动清除。
答案 1 :(得分:1)
是的,替换智能指针的内容将释放以前保留的资源。您无需显式调用reset()
(也不会有人期望您)。
答案 2 :(得分:1)
仅出于此特定示例。您的示例中的多态似乎不允许您从输出中得出明确的结论:
act from A
destroyed A
act from B
destroyed from B
destroyed A
因此,让我们简化您的示例,并使其直截了当:
#include <iostream>
#include <memory>
struct A {
explicit A(int id): id_(id)
{}
~A()
{
std::cout << "destroyed " << id_ << std::endl;
}
int id_;
};
int main() {
std::unique_ptr<A> pP{std::make_unique<A>(1)};
pP = std::make_unique<A>(2);
}
输出:
destroyed 1
destroyed 2
我希望这不会造成误解。