有没有更惯用的方法来替换指针

Is there a more idiomatic way of replacing a pointer?

本文关键字:替换 指针 方法 有没有      更新时间:2023-10-16

考虑以下代码:

#include <memory>
#include <stdio.h>
#include <stdexcept>
class Foo {
    public:
        Foo(int n) { val =n; printf("Hi %dn", val); };
        ~Foo() { printf("Bye %dn", 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

这是一个人为的例子。福是一个相当乏味的人。它只是打印出有关其寿命的信息。

代码背后的逻辑是:我声明p,但我不知道它最初应该是什么。然后我决定我知道它是什么:它应该取值1。在我的真实代码中,这个值可能会持续很长时间。

过了一段时间,我决定它不应该是1,应该是2。因此,无论以前是什么,都应该被摧毁,取而代之。

到目前为止,我的理解是,上面的代码在内存管理方面很好,在异常情况下也很健壮。

有没有更惯用的说法:

p = nullptr;
p = std::make_shared<Foo>(2);

我不能只写最后一行,因为我想说,我以前拥有的东西需要被摧毁。

只给指针赋值就足以通知您不需要以前的值。你不能说它是否应该被销毁,因为它是一个共享的指针,可能有其他所有者。

在我看来,仅仅分配就足够了,但你可能更喜欢使用shared_ptr::reset()

既然你想要惯用的(好!),那就让我们习惯吧:

#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;
}

这里没有其他需要做的事情

p = std::make_shared<Foo>(2);

如果p中的上一个对象是对该对象的最后一次引用,则此行将破坏该对象。然后,它将新的shared_ptr分配给具有新值的p