а з ключових причин того, що покажчик підкласу може передаватися як покажчик суперкласу, полягає в тому, що колись суперклас вперше з'являється в підкласі. Розглянемо простий приклад наслідування у класах. p align="justify"> Base {a; b; f1 (); Derived: public Base {c;
} object;
Розглядаючи розміщення об'єкта похідного класу Derived в пам'яті, наприклад, за допомогою команди відладчика Inspect, можна отримати кілька спрощену графічну діаграму, яка наведена на рис. 1. br/>
Base ** Base
Derived
Рис. 1. Схема розміщення в пам'яті простого похідного класу
Якщо Derived * переданий у функцію, яка очікує отримання Base *, ніяких проблем не виникає. Клас Derived збігається з класом Base у всьому, що стосується його частини, перекривається з Base. Те ж саме стосується і виклику функції object.f1 (). Переданий покажчик this має одне і те ж значення безвідносно до типу. Однак щодо класу Derived з множинним спадкуванням сказане раніше буде несправедливо. p align="justify"> Розглянемо приклад.
програмний спадкування клас
struct Base1 {a; float b; f1 ();
}; Base2 {c; d; f2 ();
}; Derived: public Base1, public Base2 {e;
} object;
Орієнтовна схема пам'яті для цього випадку показана на рис. 2. p align="justify"> Клас Base2 більше перебуває на початку класу Derived. Якщо спробувати передати Derived * функції, яка чекає надходження Base1 *, то проблем не виникне. Разом з тим, при виклику функції, яка чекає надходження Base2 *, отриманий їй адресу виявиться неправильним. p align="justify"> Щоб виправити цю адресу, необхідно додати до адресою Derived :: object зміщення Base2 в Derived, таким чином, щоб результат вказував на ту частину, яка відноситься до Base2. Така ж корекція повинна виконуватися для кожного випадку приведення типу покажчиків з Derived * в Base2 *, включаючи і прихований покажчик this, переданий компонентним функціям Base2. br/>
Base1 **
Base 1
* Derived
Base 2
Рис. 2. Схема розміщення в пам'яті класу з множинним спадкуванням
object;. f2 ()// Перед передачею в f2 () адреса об'єкта object
// повинен бути відповідно скоригований
З тих же причин C + + також повинен виконати корекцію і при зворотному приведенні типу з Base2 * в Derived *.
4. Віртуальне спадкування
У наступному прикладі клас Derived успадковує властивості двох копій класу Base: однією через к...