class A
{
public:
void Normal()
{
Virtual();
}
virtual void Virtual()
{
// это не вызовется - ОК
}
};
class B : public A
{
public:
virtual void Virtual() override
{
// это вызовется - ЧЕ ЗА?
}
~B()
{
Normal();
}
};
class C : public B
{
public:
virtual void Virtual() override
{
// это не вызовется - ЧЕ ЗА?
}
};
int _tmain(int argc, _TCHAR* argv[])
{
C c;
return 0;
}
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
B>class A
B>{
B>public:
B> void Normal()
B> {
B> Virtual();
B> }
B> virtual void Virtual()
B> {
B> // это не вызовется - ОК
B> }
B>};
B>class B : public A
B>{
B>public:
B> virtual void Virtual() override
B> {
B> // это вызовется - ЧЕ ЗА?
B> }
B> ~B()
B> {
B> Normal();
B> }
B>};
B>class C : public B
B>{
B>public:
B> virtual void Virtual() override
B> {
B> // это не вызовется - ЧЕ ЗА?
B> }
B>};
B>int _tmain(int argc, _TCHAR* argv[])
B>{
B> C c;
B> return 0;
B>}
B>
Деструктора C нет, соответтственно вызывается базовый класса B, в момент вызова деструктора класса B таблицы виртуальных функций класса C уже нет. Поэтому и вызывается B::Virtual (через вызов A::Normal)
По моему так!?!
Здравствуйте, Barbar1an, Вы писали:
B>а зачем так сделали?
Думаю потому, что ты можешь в этих виртуальных методах обратиться к недосозданным (для конструктора) или уже уничтоженным (для деструктора) членам класса (и базам).
В Delphi так не сделали, но там классы всегда в куче, и всегда по умолчанию зануляются, так что там просто делают проверки на созданность.
MSVC-specific: можно отказаться от инициализации vtable в базе, через __declspec(novtable), тогда в базовых конструкторе/деструкторе вообще нельзя вызывать виртуальные методы.
Здравствуйте, Alexander G, Вы писали:
AG>Тю, во всех учебниках по С++ про это есть, наверное.
AG>Плюс даже ворнинги статических анализаторов.
AG>Когда деструктор B вызывается, это уже эеземпляр B, а не C. AG>Технически это сделано переприсвоением vtable указателя. AG>То же самое с конструкторами.
а зачем так сделали?
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.