Re: Множественное наследование: разминка для мозгов
От: pdx Мальта http://dottedmag.net/
Дата: 06.02.02 07:30
Оценка:
Здравствуйте Roman Fadeyev, Вы писали:


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


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

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


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



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

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

RF>    return 0;
RF>}
RF>


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


RF>Кому в лом это компилить, скажу что первый вариант вызова функции выдаст что-то типа

RF>"a:2 b:1234567". Т.е. адресация СДВИНУЛАСЬ на размер класса A, и поле a теперь на самом деле попадает на поле b, а поле b — сами видите куда.

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


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


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


А такие вещи в учебниках не пишут. Тут нужно что-либо посерьезнее. Для примера, "C++ for Real Programmers" Элджера. Там все это хорошо прописано. И вообще книга полезная. Не для практического применения , а для расширения мировоззрения .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.