Как я могу вызвать приватный деструктор из shared_ptr? - PullRequest
7 голосов
/ 20 ноября 2011

У меня есть класс resource_manager, который поддерживает std::vector<boost::shared_ptr<resource> > внутри.resource_manager - это класс друзей resource.Я хочу, чтобы resource s создавался / удалялся только resource_manager, поэтому я сделал его конструкторы приватными (что работает нормально).

Однако, если я сделаю деструктор приватным, код не скомпилируется, потому что деструктор вызывается boost::shared_ptr, который не является другом resource.Я думаю о применении правила «не удалять клиентами», возвращая только const resource* из resource_manager, но почему-то я не удовлетворен безопасностью, которую обеспечивает этот метод (что, если клиент каким-то образом происходит через указательнеконстантный?)

Помимо очевидного решения не использовать shared_ptr, есть ли у вас какое-нибудь обходное / лучшее решение моей проблемы?

Ответы [ 2 ]

11 голосов
/ 20 ноября 2011

Вы можете передать пользовательское средство удаления на общий указатель. Так что просто создайте функтор удаления или функцию (до вас), которая, в свою очередь, является friend вашего класса:

class Secret
{
  ~Secret() { }
  friend class SecretDeleter;
  friend void SecretDelFunc(Secret *);
};

class SecretDeleter
{
public:
  void operator()(Secret * p) { delete p; }
};

void SecretDelFunc(Secret * p) { delete p; }

std::shared_ptr<Secret> sp1(new Secret, SecretDeleter());
std::shared_ptr<Secret> sp2(new Secret, SecretDelFunc);
1 голос
/ 20 ноября 2011

Возможно, объявить shared_ptr<resource> как друга? shared_ptr не вызывает конструктор и должен уничтожаться, только если ваш менеджер ресурсов освобождает указатель до того, как все клиенты уничтожат свои shared_ptrs. Это не позволит клиентам нарушить защиту, но позволит клиентам поддерживать ресурс против воли resource_manager.

...