2016-04-17 4 views
2

Я пытаюсь решить небольшую тайну о коде, подобной следующему:C++: полиморфизм + множественный порядок наследования. Является ли порядок наследования значительным?

struct Interface { 
    virtual void f() = 0; 
} 

struct SomeClass { 
    virtual void additionalBehaviour() = 0; 
    void g() { 
     additionalBehavoiur(); 
     /*Some stuff with printing into a ostringstream*/ 
    } 
} 

struct Derived : public SomeClass, public Interface { 
    void additionalBehaviour() { /*Some printing to oss*/ } 
    void f() { g(); } 
} 

int main() { 
    unique_ptr<Interface> ifc (new Derived()); 
    ifc->f(); 
    cout << "HI!" << endl; 
    return 0; 
} 

Он работает, но завершает работу случайным образом вызывая с0000005 0a9e APPCRASH на Windows, сделав вещи, перечисленные в g() частично и имеющих напечатано «HI!».
Итак, в какой-то момент он прекращает печать в файл, заканчивает все остальное и, наконец, сбой. Некоторая точка означает действительно пункт: например, file << "phrase" может производить phra и ничего после этого.
Кроме того, он выполняется правильно и не сбой при выполнении в GDB. И, по словам доктора памяти, утечек памяти нет.

Решение:

struct Derived : public Interface, public SomeClass { 
    void f() { g(); } 
} 

Вопрос: почему ?!
Я полагаю, что это что-то относительно относительных позиций поля в классах, но как насчет отсутствия сбоев в GDB и никаких признаков проблем с памятью?

+4

_ "Я пытаюсь решить небольшую тайну о коде * * аналогично следующему ** «_ Не отправляйте код, который не проявляет проблемного поведения. Сделайте [MCVE]. Судя по указанному вами коду, вы забыли сделать виртуальный деструктор. –

+1

@Revolver_Ocelot Проблема может быть полностью воспроизведена. Я систематически запускаю ошибку времени выполнения: http://ideone.com/djvWKO – Christophe

+0

Это 'SomeClass' и' Interface 'отсутствует виртуальный деструктор. –

ответ

4

Похоже, что проблема связана с тем, что у вас нет виртуального деструктора. Вот почему выполняется обработка в g(): авария происходит, когда unique_ptr уничтожает объект.

Как это должно работать:

struct Interface { 
    virtual void f() = 0; 
    virtual ~Interface() {}; 
}; 

Online demo

Стандартная ссылка:

5.3.5/3: In the first alternative (delete object), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.