Убедитесь, что во время компиляции объекты создаются как shared_ptr. - PullRequest
0 голосов
/ 27 декабря 2018

Есть классы, которые я пишу (часто как часть boost::asio), чьи объекты зависят от того, заключены ли они в shared_ptr, потому что они используют shared_from_this().Есть ли способ предотвратить компиляцию объекта, если он не был создан в shared_ptr?

Итак, что я ищу:

std::shared_ptr<MyClass> a = std::make_shared<MyClass>(); // should compile fine
std::unique_ptr<MyClass> a = std::make_unique<MyClass>(); // compile error
MyClass a; // compile error

1 Ответ

0 голосов
/ 27 декабря 2018

Сделайте его конструктор закрытым и присвойте ему статическую функцию-фабрику, которая создает shared_ptr.Не забудьте документировать свое дизайнерское решение в комментарии!

// Thing that foos the bar
struct Foo : std::enable_shared_from_this<Foo>
{
   // Returns a shared_ptr referring to a new instance of Foo
   static std::shared_ptr<Foo> CreateShared()
   {
      return std::shared_ptr<Foo>(new Foo);
   }

private:
   // To avoid bugs due to the shared_from_this base,
   // we restrict Foo creation to being via CreateShared().
   Foo() = default;
};

(я не могу представить, что std::make_shared будет работать из-за частного ctor, но вы можете попробовать это).

Я должен сказать, что это не похоже на то, за что должен отвечать класс.Это своего рода программирование в обратном направлении.

Воровать Eljay * слова :

В общем, лучше (если возможно)что объекты не осознают себя, если они содержатся в shared_ptr, или в куче, или в стеке, или по указателю, или в векторе, или как элемент данных, или как глобальный.Как только они осознают, как они управляют жизненным циклом, они становятся намного более ограниченными.Излишне так.shared_from_this является (возможно) анти-паттерном.Но ... иногда это может быть необходимым анти-паттерном.

Я бы предпочел избегать enable_shared_from_this и позволять людям использовать ваш Foo так, как они считают нужным, например, через хороший наклон unique_ptr.

...