Множественное наследование: разминка для мозгов
От: Roman Fadeyev  
Дата: 06.02.02 06:41
Оценка: 1 (1)
Здравствуйте.

Когда-то я наступил на грабли множественного наследования. А сегодня, вспомнив об этом,
хочу подсунуть их вам, подогреть, так сказать, форум.

Ниже приведены три класса: два базовых и один их наследник


class A{
public:
    int a;
};
class B{
public:
    int b;
};

class C:public A,public B
{
public:
    void Test(){
        cout<<"a:"<<a<<"  b:"<<b;
    }
};


Теперь выполняем сей код:


int main(int argc, char* argv[])
{
    typedef void (B::*pClassB_Func)();
    C TestC;    //Итак, имеем класс C - наследник A+B
    TestC.a=1;  //Это поле от A
    TestC.b=2;  //Это поле от B
    pClassB_Func pf=static_cast<pClassB_Func>(C::Test); //Указатель на функцию  void C::Test()

    //Вот это, казалось бы безобидный вариант. Но неправильный
    B * pB=&TestC;
    (pB->*pf)();
    //Вот это очень ужасный на вид, но РАБОЧИЙ вариант
    pB=static_cast<B*>((void*)&TestC);
    (pB->*pf)();

    return 0;
}


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

Кому в лом это компилить, скажу что первый вариант вызова функции выдаст что-то типа
"a:2 b:1234567". Т.е. адресация СДВИНУЛАСЬ на размер класса A, и поле a теперь на самом деле попадает на поле b, а поле b — сами видите куда.

Во втором случае все прекрасно.

Пораскинув мозгами, поведение компилятора можно понять: мы просили указатель на базовый класс B, он нам его и дал, слегка сместив. Во втором случае имеем передачу адреса (void*), и компилятор послушно ее выполняет.

Ответа я, собственно, не прошу. Просто хочу показать фишку. Ни в одном учебнике по С++, что я читал, такого примера не встречал, так что может кому сберегу лоб (см грабли)

Если у кого есть похожие байки, или он хочет чё-нить выразить по поводу сабжа, или хочет назвать меня ослом, буду рад выслушать
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.