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

时间:2016-04-03 09:04:57

标签: c++ memory

请考虑以下代码:

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

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

3 个答案:

答案 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