Множественное наследование и виртуальные методы
От: leshi Россия  
Дата: 22.02.04 10:03
Оценка:
У меня возникла проблема, которую я на трамвае объехал, но остался неприятный осадок. Что-то я делаю не так, как надо.
Поиск смотрел, если там и есть то, что мне надо, я не понял того, что там написано.
Ситуация такая:
class Base
{
public:
    virtual void funcBase();
}
class BaseA
{
public:
    virtual void funcBaseA();
}

class Impl: public Base, public BaseA
{
public:
    virtual void funcBase();
    void funcImpl();
}
class Store
{
    public:
    Base *pBase;
}
//Где-то идет объявление Store *s;
void someInit()
{
    s=new Store;
    s->pBase=new Impl;
/*
на самом деле классов типа Impl множество, все они наследуют 
разные базовые классы, но все наследуются от Base. 
Часть из них переопределяет часть методов базовых классов.
*/    
}
void someUsage()
{
// В данном случае, я полностью уверен, что s->pBase указывает на объект, 
// наследованный от BaseA
//    BaseA *pBaseA=reinterpret_cast(s->pBase); Так не работает, выдает из глубин ассемблера обращение к нулевому указателю.
    BaseA *pBaseA=dynamic_cast<BaseA *>(s->pBase);
    if (pBaseA!=NULL)
        pBaseA->funcBaseA(); // Вот тут проблема.
}

void someUsage_correct()
{
    Impl *pImpl=dynamic_cast<Impl *>(s->pBase);
    if (pImpl!=NULL)
        pImpl->funcBaseA(); // так работает правильно и всегда
}


А проблема в том, что в someUsage() вызывается не BaseA::funcBaseA(), а нечто странное .
Причем someUsage_correct() всегда работает правильно. Но проблема в том, что таких классов, как Impl (в частности наследованных и от BaseA) у меня много. Для каждого пришлось определить свою someUsage_correct(). Вот это ИМХО не правильно.
Самое смешное, что вызов как в someUsage() проходит правльно в половине случаев, а в другой половине валится на неправильный виртуальный метод.
Подскажите, в какой цепочке ДНК искать ошибку?

ЗЫ: Именно этот код я не проверял, но смысл ситуации он передает верно.
ЗЫЫ: Компилятор VC6, VC7.0, VC7.1. Пока ряд компиляторов был не таким длинным, я думал, что с моим ДНК все в порядке... Как жестоко я ошибался!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.