Это сообщение — комментарий к странице
"Deep C++ > А чисто виртуальные деструкторыАвтор: Павел Кузнецов
Дата: 03.04.03
— бывают?", но она закрыта? (
У многих компиляторов вызов виртуальных деструкторов при нестандартном управлении памятью происходит неправильно.
cl выдержал все проверки, только со второй формой оператора
delete, по видимости, есть некоторые проблемы:
| | Текст virtual destructors.cpp |
| | #include <stddef.h>
#include <stdio.h>
class A {
int ma;
public:
A ();
virtual ~A ();
void *operator new (size_t size);
void operator delete (void *p, size_t size);
void *operator new [] (size_t size) { return operator new (size); }
void operator delete [] (void *p, size_t size) { operator delete (p, size); }
};
class B : public A {
int mb;
public:
B ();
virtual ~B ();
};
int main ()
{
A *pa = new B;
delete pa;
A *paa = new B [2];
delete [] paa;
return 0;
}
A::A () { printf ("A::A()\n"); }
B::B () { printf ("B::B()\n"); }
A::~A () { printf ("A::~A()\n"); }
B::~B () { printf ("B::~B()\n"); }
void* A::operator new (size_t size)
{
void *p;
p = ::operator new (size);
printf ("A::operator new (%u) = <%08x>\n", size, p);
return p;
}
void A::operator delete (void *p, size_t size)
{
::operator delete (p);
printf ("A::operator delete (<%08x>, %u)\n", p, size);
}
|
| | |
Результаты работы:
| | Результаты |
| | Оптимизирующий 32-разрядный компилятор Microsoft (R) C/C++ версии 16.00.30319.01 для 80x86:
A::operator new (12) = <00334fc8>
A::A() B::B () B::~B () A::~A()
A::operator delete (<00334fc8>, 12)
A::operator new (28) = <003328b8>
A::A () B::B () A::A () B::B ()
B::~B() A::~A() B::~B() A::~A()
A::operator delete (<003328b8>, 12)
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86:
A::operator new (12) = <00332bc8>
A::A() B::B() B::~B() A::~A()
A::operator delete (<00332bc8>, 12)
A::operator new (28) = <00332be0>
A::A () B::B () A::A () B::B ()
B::~B() A::~A() B::~B() A::~A()
A::operator delete (<00332be0>, 12)
Intel(R) C++ Compiler for 32-bit applications, Version 9.0:
A::operator new (12) = <00333db8>
A::A() B::B() B::~B() A::~A()
A::operator delete (<00333db8>, 12)
A::operator new (28) = <00332bb0>
A::A() B::B() A::A() B::B() A::~A() A::~A()
A::operator delete (<00332bb0>, 0)
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland:
A::operator new (12) = <00852d14>
A::A() B::B() B::~B() A::~A()
A::operator delete (<00852d14>, 12)
A::operator new (28) = <00852d14>
A::A() B::B() A::A() B::B() A::~A() A::~A()
A::operator delete (<00852d14>, 16)
Borland C++ 5.0 Copyright (c) 1987, 1996 Borland International:
A::operator new (6) = <00000e42>
A::A() B::B() B::~B() A::~A()
A::operator delete (<00000e42>, 6)
A::operator new (16) = <00000e42>
A::A () B::B () A::A () B::B ()
A::~A() A::~A() A::~A() A::~A()
A::operator delete (<00000e42>, 8)
Borland C++ Version 3.1 Copyright (c) 1992 Borland International
A::operator new (6) = <000005e2>
A::A() B::B() B::~B() A::~A()
A::operator delete (<000005e2>, 6)
A::A() B::B() A::A() B::B() A::~A() A::~A()
|
| | |
Borland провалился, даже у Intel 9 версии ошибки.
При современной технике программирования деструкторы следует объявлять виртуальными всегда.