Общие указатели на недействительные. Почему это работает?

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

Я мог бы решить эту проблему, создав какой-то корневой класс, от которого наследуются все мои другие классы, и использовать shared_ptr для этого корневого класса, например:

std::shared_ptr<Root>

Однако:

  • Я не хочу, чтобы все мои классы унаследовали от этого корневого класса class только для того, чтобы иметь этот общий указатель
  • Иногда я хочу вернуть общий указатель на std :: vector, или std :: list, или std :: set, ... которые явно не наследуются от моего корневого класса

Достаточно странно, кажется, что вы можете создать shared_ptr на void, и это, похоже, работает правильно, как показано в этом примере:

class X
   {
   public:
      X() {std::cout << "X::ctor" << std::endl;}
      virtual ~X() {std::cout << "X::dtor" << std::endl;}
   };

typedef std::shared_ptr<void> SharedVoidPointer;

int main()
{
X *x = new X();
SharedVoidPointer sp1(x);
}

x удален правильно, и в более крупном эксперименте я мог убедиться, что общий указатель действительно делает то, что ему нужно (удаление x после последнего shared_ptr выключает свет).

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

Но гарантированно ли это будет работать во всех случаях? Он явно работает в Visual Studio 2010, но правильно ли это работает и на других компиляторах? На других платформах?

20
задан James McNellis 10 March 2012 в 04:23
поделиться