请考虑以下代码:
#include <memory>
#include <stdio.h>
#include <stdexcept>
class Foo {
public:
Foo(int n) { val =n; printf("Hi %d\n", val); };
~Foo() { printf("Bye %d\n", val); };
private:
int val;
};
int main()
{
std::shared_ptr<Foo> p = nullptr; // I don't know what I want yet
p = std::make_shared<Foo>(1); // OK, I've decided
// I've changed my mind, it needs to be something else
p = nullptr;
p = std::make_shared<Foo>(2);
return 0;
}
它的输出是:
Hi 1
Bye 1
Hi 2
Bye 2
这是一个人为的例子。 Foo是一个相当无趣的人。它只打印出有关其生命周期的信息。
代码背后的逻辑是:我宣布p,但我不知道最初应该是什么。然后我决定我知道它是什么:它应该取值1.在我的实际代码中,这个值可能会持续很长时间。
一段时间之后,我认为它不应该是1,它应该是2.所以以前的任何东西都应该被销毁,并被其他东西取代。
到目前为止,我的理解是上面的代码在内存管理方面很好,并且在异常情况下是健壮的。
是否有更惯用的说法:
p = nullptr;
p = std::make_shared<Foo>(2);
我不能写最后一行,因为我想说我以前拥有的东西需要被销毁。
答案 0 :(得分:2)
只需指定指针即可告知您不需要以前的值。你不能说它是否应该被销毁,因为它是共享的指针,可能还有其他所有者。
在我看来,只需分配即可,但您可能更愿意使用shared_ptr::reset()
。
答案 1 :(得分:1)
既然你想要惯用语(好!),那就是惯用语:
#include <memory>
#include <stdexcept>
#include <iostream>
class Foo {
public:
Foo(int n)
: val(n)
{
std::cout << "Hi " << val << "\n";
};
~Foo() {
std::cout << "bye " << val << "\n";
};
private:
int val;
};
int main()
{
auto p = std::shared_ptr<Foo>(); // I don't know what I want yet
p = std::make_shared<Foo>(1); // OK, I've decided
// I've changed my mind, it needs to be something else
p = std::make_shared<Foo>(2);
return 0;
}
答案 2 :(得分:1)
你不需要在这里做任何其他事情
p = std::make_shared<Foo>(2);
如果该行是对该对象的最后一个引用,则该行将销毁p中的上一个对象。然后它使用新值
将新的shared_ptr分配给p