2012-04-18 2 views
1

Можно ли вызвать деструктор объекта без знания типа класса без использования delete? Я спрашиваю, потому что я работаю над распределителем (для удовольствия/практики), и я использую malloc/размещение new для создания объекта, но затем, когда я иду на уничтожение объекта, мне было любопытно, если бы был способ сделать это без зная тип. Если это невозможно, почему бы и нет? Это единственный способ сделать это, как я показываю в своем примере кода (который прокомментирован)?Можно ли вызвать деструктор, не зная тип?

#include <stdio.h> 
#include <new> 

void* SomeAllocationFunction(size_t size) { 
    return malloc(size); 
} 

class SomeClass{ 
public: 
    SomeClass() { 
     printf("Constructed\n"); 
    } 

    ~SomeClass() { 
     printf("Destructed\n"); 
    } 
}; 

int main(void){ 
    void* mem = SomeAllocationFunction(sizeof(SomeClass)); 
    SomeClass* t = new(mem)SomeClass; 

    free(t); 
    //t->~SomeClass(); // This will call the destructor, is it possible to do this without knowing the class? 

    return 0; 
} 

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

+0

Единственный способ назвать класс конкретными функция, не зная класса во время компиляции, - это если в каждом экземпляре имеется определенная информация о конкретном классе, которая может использоваться для выполнения поиска во время выполнения (аналогично концепции vtbl). Это вообще не так. –

+3

Когда вы в конечном итоге вызываете 't-> ~ SomeClass()', вы обязательно захотите сделать это * перед * 'free (t)'. –

+0

@Greg Hewgill: Это был только что прокомментированный код, я не хотел путать с приказом. – mmurphy

ответ

2

Нет, это невозможно без знания типа (или знания одного из базовых типов объекта, который имеет виртуальный деструктор).

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

(Технически, вы могли бы связать с каждым распределением функции указателя, который заканчивается вызовом деструктора типа. Но это довольно схематично, и я бы не рекомендовал его.)

+0

Я полагаю, тогда оболочке нужно было бы знать тип для прямого вызова деструктора? (Как макрос) – mmurphy

+0

Да; это будет шаблон для типа уничтожаемого объекта. Однако не нужно было бы смотреть иначе, чем вызов free(), потому что тип можно было бы вывести. –

2

Нет, вы не можете вызывать деструктор, не зная класс, потому что компилятор не знает который деструктор вызывает. Вы можете либо:

  • Сделать все объекты наследуют от некоторого базового объекта, который имеет виртуальный деструктор, и использовать этот указатель базового объекта, а не пустой указатель
  • использование Make шаблонов
  • У самого аллокатора не управлять вызовом конструкторов/деструкторов
2

Невозможно вызвать деструктор на нетипизированную часть памяти, чем вызвать конструктор (то есть: размещение нового) без типа. И конструктор, и деструктор являются частью объекта, а компилятору нужен тип, чтобы знать, что нужно вызвать.

Смежные вопросы