Виртуальная табличная схема С++ для MI (множественное наследование)
Посмотрите на следующий код на С++
class Base1 {
public:
Base1();
virtual ~Base1();
virtual void speakClearly();
virtual Base1 *clone() const;
protected:
float data_Base1;
};
class Base2 {
public:
Base2();
virtual ~Base2();
virtual void mumble();
virtual Base2 *clone() const;
protected:
float data_Base2;
};
class Derived : public Base1, public Base2 {
public:
Derived();
virtual ~Derived();
virtual Derived *clone() const;
protected:
float data_Derived;
};
Внутри "Объектной модели С++" 4.2 говорится, что виртуальная табличная раскладка классов Base1, Base2 и Derived выглядит так:
![enter image description here]()
![enter image description here]()
Мой вопрос:
Виртуальная таблица SubObject Base1 класса Derived содержит Base2::mumble
.Почему? Я знаю, что Derived class поделился этой виртуальной таблицей с Base1, поэтому я думаю, что функция Base2 не должна появляться здесь. Может ли кто-нибудь сказать мне, почему? спасибо.
Ответы
Ответ 1
Хорошо, прежде всего, я напомню всем, что дизайн решения для реализации полиморфизма является решением ABI за пределами Стандарта. Например, MSVC и Itanium ABI (за ними следуют gcc, clang, icc,...) имеют разные способы реализации этого.
С этой точки зрения, я думаю, что это оптимизация для поиска.
Всякий раз, когда у вас есть объект Derived
(или один из его потомков) и ищет элемент mumble
, вам не нужно действительно обнаруживать подобъект Base2
, но может непосредственно действовать из подобъекта Base1
адрес которого совпадает с подобъектом Derived
, поэтому не задействована арифметика).
Ответ 2
Во время выполнения, когда вы получаете:
Base2 b2;
Base1* b1_ptr = (Base1*)&b2;
b1_ptr->mumble(); // will call Base2::mumble(), this is the reason.
Затем необходимо вызвать Base2:: mumble()!
Позаботьтесь о том, чтобы mumble() был единственным виртуальным методом, который был переоценен в иерархии.
(Даже, вы можете думать, что clone() слишком сильно переопределен, но он возвращает другой тип среди классов, тогда это еще одна подпись).