Вам нужно передать delete тот же указатель, который был возвращен новым, или вы можете передать ему указатель на один из базовых типов классов? Например:
class Base
{
public:
virtual ~Base();
...
};
class IFoo
{
public:
virtual ~IFoo() {}
virtual void DoSomething() = 0;
};
class Bar : public Base, public IFoo
{
public:
virtual ~Bar();
void DoSomething();
...
};
Bar * pBar = new Bar;
IFoo * pFoo = pBar;
delete pFoo;
Конечно, это значительно упрощается. Что я действительно хочу сделать, так это создать контейнер, полный boost :: shared_ptr, и передать его некоторому коду, который удалит его из контейнера после его завершения. Этот код ничего не будет знать о реализации Bar или Base и будет полагаться на подразумеваемый оператор удаления в деструкторе shared_ptr, чтобы делать правильные вещи.
Может ли это сработать? Моя интуиция говорит «нет», поскольку указатели не будут иметь один и тот же адрес. С другой стороны, dynamic_cast должен работать, поэтому где-то компилятор хранит достаточно информации, чтобы понять это.
Спасибо за помощь всем, кто ответил и прокомментировал. Я уже знал важность виртуальных деструкторов, как показано в моем примере; Увидев ответ, я немного подумал и понял,
вся причина для виртуального деструктора - именно этот сценарий. Таким образом, это должно было работать. Меня бросило отсутствие видимого средства преобразования указателя обратно в оригинал. Немного больше размышлений заставило меня поверить, что существуют невидимые средства, и я предположил, что деструктор возвращает истинный указатель для удаления, чтобы освободить. Исследование скомпилированного кода из Microsoft VC ++ подтвердило мои подозрения, когда я увидел эту строку в ~ Base:
mov eax, DWORD PTR _this$[ebp]
Трассировка ассемблера показала, что это был указатель, передаваемый в функцию удаления. Тайна раскрыта.
Я исправил пример добавления виртуального деструктора в IFoo, это был простой недосмотр. Еще раз спасибо всем, кто указал на это.