Указатель на деструктор
От: Chez Россия  
Дата: 05.08.04 14:43
Оценка:
Можно ли имея указатель на произвольный класс (зная о классе только то, что у него есть виртуальный деструктор), получить указатель на этот деструтор и вызвать его?

Я предположил, что указатель на вирт. деструктор располагается в vTable где-то в определённом месте. К тому же деструеторы не имеют параметров. Значит можно реализовать такую функцию:
void DeleteObject(void* object_pointer)
{
   call_destructor(object_pointer); // ХЗ как это сделать
     free(object_pointer);
}

Это было бы очень полезно в случае класса CUnknown:
вместо
template<class T>
class CUnknown
{
    CUnknown(T* pObj)
    virtual void AddRef() { ... }   // Исплементация виртуальной функции темплейтного класса
    virtual void Release() { ... }  // Хреновый код!
}
можно было бы
class CUnknown
{
    CUnknown(void* pObj);
    virtual void AddRef(); // Реализация единственна и в .CPP
    virtual void Release(); // Хороший код!
};
Поскольку классу CUnknown требуется только УДАЛЕНИЕ объекта по указателю pObj

Кто глубоко ковырял компиляторы, может знает ответ?..
Re: Указатель на деструктор
От: Bell Россия  
Дата: 05.08.04 14:47
Оценка:
Здравствуйте, Chez, Вы писали:

C>Можно ли имея указатель на произвольный класс (зная о классе только то, что у него есть виртуальный деструктор), получить указатель на этот деструтор и вызвать его?


Нет:
12.4/2
...
The address of a destructor shall not be taken.
...
Любите книгу — источник знаний (с) М.Горький
Re[2]: Указатель на деструктор
От: Chez Россия  
Дата: 05.08.04 14:51
Оценка: :)
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, Chez, Вы писали:


C>>Можно ли имея указатель на произвольный класс (зная о классе только то, что у него есть виртуальный деструктор), получить указатель на этот деструтор и вызвать его?


B>Нет:

B>
B>12.4/2
B>...
B>The address of a destructor shall not be taken.
B>...
B>

Тут написано shall... Т.е. это можно, но не нужно.
Он то всё-таки есть, этот адрес!
CDestructor как вариант
От: Chez Россия  
Дата: 05.08.04 15:03
Оценка:
Здравствуйте, Chez, Вы писали:

А если сделать так:
class CDestructor
{
public:
virtual ~CDestructor();
};

Все классы до единого наследовать от CDestructor виртуально
Можно ли бы уверенным, что функция
template<class T>
void Destruct(T* p) { delete static_cast<CDestructor*>(p); }
Будет удалять всегда все объекты из памяти вызывая правильно свои деструкторы, несмотря на количество наследований, количество CDestructor-ов... количество предков... ???
Re: Указатель на деструктор
От: Glоbus Украина  
Дата: 05.08.04 15:04
Оценка:
Здравствуйте, Chez, Вы писали:

C>Можно ли имея указатель на произвольный класс (зная о классе только то, что у него есть виртуальный деструктор), получить указатель на этот деструтор и вызвать его?


А тип указателя не известен?
То есть можно было бы конечно написать нечто вроде

template<class T>
void DeleteObject( T& _obj )
{
    _obj.~T();
    free( &_obj );
}


Правда с временныи объектами такой код породит полный писец. Кроме того, если есть только указатель void* я че-то слабо представляю как по нему можно определить адрес чего бы то ни было.


C>Я предположил, что указатель на вирт. деструктор располагается в vTable где-то в определённом месте. К тому же деструеторы не имеют параметров. Значит можно реализовать такую функцию:

C>
void DeleteObject(void* object_pointer)
C>{
C>   call_destructor(object_pointer); // ХЗ как это сделать
C>     free(object_pointer);
C>}

C>Это было бы очень полезно в случае класса CUnknown:
C>вместо
C>template<class T>
C>class CUnknown
C>{
C>    CUnknown(T* pObj)
C>    virtual void AddRef() { ... }   // Исплементация виртуальной функции темплейтного класса
C>    virtual void Release() { ... }  // Хреновый код!
C>}
можно было бы
C>class CUnknown
C>{
C>    CUnknown(void* pObj);
C>    virtual void AddRef(); // Реализация единственна и в .CPP
C>    virtual void Release(); // Хороший код!
C>};
C>
Поскольку классу CUnknown требуется только УДАЛЕНИЕ объекта по указателю pObj


C>Кто глубоко ковырял компиляторы, может знает ответ?..
Удачи тебе, браток!
Re: CDestructor как вариант
От: Анатолий Широков СССР  
Дата: 05.08.04 15:08
Оценка:
Если наследоваться от CDestructor, то все будет освобождаться корректно:

void Destruct(CDestructor* p) { delete p; }
Re[3]: Указатель на деструктор
От: Павел Кузнецов  
Дата: 05.08.04 15:27
Оценка:
Chez:

> C>>Можно ли имея указатель на произвольный класс (зная о классе только то, что у него есть виртуальный деструктор), получить указатель на этот деструтор и вызвать его?


> B>Нет: 12.4/2 ... The address of a destructor shall not be taken.


> Тут написано shall... Т.е. это можно, но не нужно.


В стандарте "shall not" означает "нельзя", а т.к. реализации обычно выдают диагностику на использование подобных конструкций, то на практике — "невозможно".
Posted via RSDN NNTP Server 1.9 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: Указатель на деструктор
От: Piter  
Дата: 05.08.04 15:50
Оценка:
C>Можно ли имея указатель на произвольный класс (зная о классе только то, что у него есть виртуальный деструктор), получить указатель на этот деструтор и вызвать его?

C>Я предположил, что указатель на вирт. деструктор располагается в vTable где-то в определённом месте. К тому же деструеторы не имеют параметров. Значит можно реализовать такую функцию:

C>
void DeleteObject(void* object_pointer)
C>{
C>   call_destructor(object_pointer); // ХЗ как это сделать
C>     free(object_pointer);
C>}

C>Это было бы очень полезно в случае класса CUnknown:
C>вместо
C>template<class T>
C>class CUnknown
C>{
C>    CUnknown(T* pObj)
C>    virtual void AddRef() { ... }   // Исплементация виртуальной функции темплейтного класса
C>    virtual void Release() { ... }  // Хреновый код!
C>}
можно было бы
C>class CUnknown
C>{
C>    CUnknown(void* pObj);
C>    virtual void AddRef(); // Реализация единственна и в .CPP
C>    virtual void Release(); // Хороший код!
C>};
C>
Поскольку классу CUnknown требуется только УДАЛЕНИЕ объекта по указателю pObj


Можно унаследовать классы всех объектов используемых с CUnknown от обшего класса с пустым виртуальным деструктором. И преобразовывать не в void* a в указатель на этот класс и т.д. Переносимо, единственное размер обектов увеличится на размер указателя.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.