Получение unique_ptr для класса, который наследует enable_shared_from_this

Обычно я предпочитаю возвращатьсяunique_ptr с заводов. Недавно я пришел к проблеме возвращенияunique_ptr для класса, который наследуетenable_shared_from_this, Пользователи этого класса могут случайно вызвать звонокshared_from_this(), хотя он не принадлежит никомуshared_ptr, что приводит кstd::bad_weak_ptr исключение (или неопределенное поведение до C ++ 17, которое обычно реализуется как исключение).

Простая версия кода:

class Foo: public enable_shared_from_this<Foo> {
    string name;
    Foo(const string& _name) : name(_name) {}
public:
    static unique_ptr<Foo> create(const string& name) {
        return std::unique_ptr<Foo>(new Foo(name));
    }
    shared_ptr<Foo> get_shared() {return shared_from_this();}
    void doIt()const {cout << "Foo::doIt() <" << name << '>' << endl;}
    virtual ~Foo() {cout << "~Foo() <" << name << '>' << endl;}
};

int main() {
    // ok behavior
    auto pb1 = Foo::create("pb1");
    pb1->doIt();
    shared_ptr<Foo> pb2 = shared_ptr<Foo>(std::move(pb1));
    shared_ptr<Foo> pb3 = pb2->get_shared();
    pb3->doIt();

    // bad behavior
    auto pb4 = Foo::create("pb4");
    pb4->doIt();
    shared_ptr<Foo> pb5 = pb4->get_shared(); // exception
    pb5->doIt();    
}

Возможное решение состоит в том, чтобы изменить заводской метод для возвратаshared_ptr но это не то, что я ищу, так как во многих случаях нет необходимости делиться, и это сделает вещи менее эффективными.

Вопрос в том, как добиться всего следующего:

разрешить фабрике вернутьсяunique_ptrразрешатьunique_ptr этого класса, чтобы стать общимразрешатьshared_ptr этого класса, чтобы получить общие копии (черезshared_from_this())избежать неудачи, когдаunique_ptr этого класса пытается получить общий доступ от этого (вызовget_shared в приведенном выше примере)

Пункты с 1 по 3 выполняются с кодом выше,проблема с пунктом 4.

Ответы на вопрос(6)

Ваш ответ на вопрос