为了避免从原始指针创建 std::shared_ptr?

To avoid creation of std::shared_ptr from raw pointers?

我目前正在关注《**Effective Modern C++》一书,上面写着

Avoid creating std::shared_ptrs from variables of raw pointer type.

而且我对解释深信不疑,因此我也同意我们需要避免。但是我遇到了一个例外。

class Person
{
protected:
    Person();
public:

    static std::shared_ptr<Person> getShared()
    {
        return std::shared_ptr<Person>(new Person());
    }

当我们隐藏默认构造函数时 std::make_shared 无法完成它的工作。这就是我在上面的示例中使用静态方法的原因。我的问题是

  1. 我能为这种情况做些什么吗?
  2. 我仍然使用原始指针来创建一个shared_ptr,但在这种情况下我可以预测这个指针可能会发生什么。这种做法是否仍然威胁我的代码?

虽然这可能不是最好的方法,但一种在一定程度上保护构造函数但仍可由 std::make_shared 调用的方法如下:

class MyClass
{
protected:
    struct ConstructorGuard {};

public:
    MyClass(ConstructorGuard g) {}

    static std::shared_ptr<MyClass> create()
    {
         return std::make_shared<MyClass>(ConstructorGuard());
    }
};

构造函数本身是 public,但不能从 class 外部调用它,因为它需要一个 ConstructorGuard 类型的参数,这是一个受保护的嵌套 class,这样只有 class 本身(和派生的 classes)可以构造这样一个对象并将其传递给构造函数。