【问题标题】:Why create an object with a static shared_ptr returning member?为什么要创建一个带有静态 shared_ptr 返回成员的对象?
【发布时间】:2020-05-06 23:49:05
【问题描述】:

我见过这样的模式,我很好奇这种模式有什么好处。用静态和纯构造函数创建对象有什么区别?

class Foo {
static std::shared_ptr<Foo> create(); // why expose this function?

Foo(folly::observer::Observe<Config> config);
};

【问题讨论】:

  • 这被称为“工厂”,它确保您可以控制创建对象的所有环境

标签: c++ constructor static


【解决方案1】:

这样做的一个原因是强制对象的所有实例由 shared_ptr 拥有(而不是静态构造)。这在使用 shared_from_this() 时特别有用。

例如,考虑以下程序:

#include <memory>

class Foo;

void globalFunc(const std::shared_ptr<Foo> &) {
    // do something with the ptr
}

class Foo
    : public std::enable_shared_from_this<Foo>
{
public:
    Foo() {}
    void classMemberFunc()
    {
        globalFunc(shared_from_this());
    }
};

在这个程序中,Foo 对象可以访问/传递一个指向自身的共享指针,类似于它访问/传递 this 指针的方式。当对 Foo 的对象调用 classMemberFunc() 时,globalFunc 会收到对持有 Foo 的 shared_ptr 的引用。

但是,在这种设计中,Foo 首先需要由 shared_ptr 拥有。

int main()
{
    // valid use
    auto sptr = std::make_shared<Foo>();
    sptr->classMemberFunc();
}

如果 Foo 对象不属于 shared_ptr,则 shared_from_this() 在 C++17 之前具有未定义的行为,并且在 C++17 中存在运行时错误。

int main()
{
    // invalid use - undefined behavior or runtime error
    Foo nonPtrFoo;
    nonPtrFoo.classMemberFunc();
}

我们希望在编译时防止这种情况发生。我们可以使用静态“create”方法和私有构造函数来做到这一点。

class Foo
    : public std::enable_shared_from_this<Foo>
{
public:
    static std::shared_ptr<Foo> create() // force shared_ptr use
    {
        return std::shared_ptr<Foo>(new Foo);
    }
    void classMemberFunc()
    {
        globalFunc(shared_from_this());
    }
private:
    Foo() {} // prevent direct construction
};

int main()
{
    // valid use
    auto sptr = Foo::create();
    sptr->classMemberFunc();

    // invalid use - now compile error
    Foo nonPtrFoo;
    nonPtrFoo.classMemberFunc();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 2019-03-03
    • 1970-01-01
    • 2023-03-06
    • 2016-09-24
    相关资源
    最近更新 更多