我应该从传递给函数的“new”中删除指针,该函数会变成“shared_ptr”吗?

Pau*_*aul 6 c++ shared-ptr c++14

在下面的代码示例中:

#include <iostream>

class Foo{
};

class Bar{
public:
    void addFoo(Foo *foo){
        auto my_foo = std::shared_ptr<Foo>(foo);
    }
};

int main() {
    auto bar = Bar();
    bar.addFoo(new Foo());
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我是否需要清理由main()调用创建的指针,或者是否会由创建它的指针bar.addFoo(new Foo)来处理?我的理解是,将使用复制构造函数将该指针复制到使原始指针悬空,这是正确的吗?Barshared_ptrauto my_foo = std::shared_ptr<Foo>(foo);my_foo

Evg*_*Evg 4

构造函数采用原始指针的真正想法是将所有权传递给std::shared_ptr. 所以,不,您不必将delete原始指针传递给std::shared_ptr. 这样做会导致双重删除,也就是UB。

请注意,通常传递原始指针是危险的。考虑以下更一般化的示例:

void addFoo(Foo *foo){
        // some code which could throw an exception
        auto my_foo = std::shared_ptr<Foo>(foo);
    }
Run Code Online (Sandbox Code Playgroud)

my_foo如果在构造之前抛出异常,foo就会泄漏。

如果您没有特殊原因传递原始指针,请考虑以下替代方案:

class Bar {
public:
    template<class... Args>
    void addFoo(Args... args){
        auto my_foo = std::make_shared<Foo>(args...);
    }  
};

int main() {
    auto bar = Bar();
    bar.addFoo();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这里,您传递参数(如果有的话)在Foo内部构造addFoo(),而不是在Foo调用之前构造addFoo()构造。

args...如果需要的话可以使用完美转发:

    template<class... Args>
    void addFoo(Args&&... args){
        auto my_foo = std::make_shared<Foo>(std::forward<Args>(args)...);
    }
Run Code Online (Sandbox Code Playgroud)