2012-05-22 4 views
17

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

pure virtual method called

SomeClass::~SomeClass() 
{ 
    BaseClassObject->SomePureVirtualMethod(this); 
} 

void DerivedClass::SomePureVirtualMethod(SomeClass* obj) 
{ 
    //Do stuff to remove obj from a collection 
} 

Я никогда не призыв к new SomeClass, но у меня есть QList<SomeClass*>, который я прилагаю SomeClass* объектов. Цель этого деструктора в SomeClass состоит в том, чтобы сообщить DerivedClass удалить конкретный экземпляр SomeClass из его коллекции QList<SomeClass*>.

Таким образом, в конкретном примере ...

BaseClass = Shape

DerivedClass = Triangle

SomeClass = ShapeProperties которому принадлежит ссылка на Shape

Таким образом, я никогда не иметь позвоните по телефону new ShapeProperties, но у меня есть QList<ShapeProperties*> внутри Triangle. Деструктор в ShapeProperties должен сообщить Triangle об удалении определенного свойства ShapeProperties из его коллекции QList<ShapeProperties*>.

ответ

28

К тому времени, как вы вызываете деструктор, деструктор унаследованных классов уже вызван. Внутри конструкторов и деструкторов динамический тип объекта можно эффективно рассматривать как то же, что и статический тип. То есть, когда вы вызываете виртуальные методы из своих конструкторов/деструкторов, это не переопределенные версии из них.

Если SomePureVirtualMethod необходимо вызвать в деструкторе, вы должны будете вызвать его в деструкторе класса, где фактическое определение метода вы хотите.

+0

Тогда как узнать, какой экземпляр 'this' я имею в виду, если я его вызываю в производном конструкторе? – user869525

+0

@ user869525: Не могли бы вы перефразировать это? Я не понял ... –

+0

Я, вероятно, неправильно понял это: «Если' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' " – user869525

8

При вызове метода virtual в деструктор базового класса SomeClass он вызывает метод (SomePureVirtualMethod()) базового класса SomeClass, который является чисто виртуальный метод, без определения. И, следовательно, ошибка.

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

Почему он падает?
Поскольку вызов чистой виртуальной функции из конструктора или деструктора является Неопределенное поведение.

C++ 03 10.4/6 состояние

«Функция-членов может быть вызван из конструктора (или деструктора) абстрактного класса, эффект создания виртуального вызова (10.3) к чистой виртуальной функции, прямо или косвенно, для объекта (или уничтоженный) от такого конструктора (или деструктора) не определено ».

Как этого избежать?
Просто убедитесь, что вы не вызываете чистую виртуальную функцию из конструктора или деструктора.
Не вызывайте методы virtual в конструкторе или деструкторе, если вы не понимаете динамику.