Re[5]: О виртуальном наследовании
От: dupamid Россия  
Дата: 09.09.02 18:03
Оценка: 14 (2)
Здравствуйте Amor, Вы писали:

A>Вообщем понятно: создается таблица в которой хранятся смещения всех базовых объектов.

A>Сам же объект класса-наследника содержит указатель на эту таблицу.
A>Что же происходит теперь?
A>
A>class C : public virtual A
A>{};
A>class D : public B, public C
A>{};
A>


Примерно следующее:

// class A
// {
//    public:
//        int a;
// };
struct _A
{
    int a;
};

// class B : virtual public A
// {
//    public:
//        int b;
// };
struct _B_Self
{
    unsigned* _vbtable;
    int b;
};

struct _B
{
    _B_Self _self;
    _A _A_base;
};

unsigned _B_vbtable[1] = { offsetof(_B, _A_base) };

void _B_ctor(_B_Self* p, bool b)
{
    if(b) p->_vbtable = _B_vbtable;
}

// class C : virtual public A
// {
//    public:
//        int c;
// };
struct _C_Self
{
    unsigned* _vbtable;
    int c;
};

struct _C
{
    _C_Self _self;
    _A _A_base;
};

unsigned _C_vbtable[1] = { offsetof(_C, _A_base) };

void _C_ctor(_C_Self* p, bool b)
{
    if(b) p->_vbtable = _C_vbtable;
}

// class D : public B, public C
// {
//    public:
//        int d;
// };
struct _D_Self
{
    _B_Self _B_base;
    _C_Self _C_base;
    int d;
};

struct _D
{
    _D_Self _self;
    _A _A_base;
};

// внимание: разное смещение!
unsigned _D_vbtable1[1] = { offsetof(_D, _A_base) - offsetof(_D_Self, _B_base) };
unsigned _D_vbtable2[1] = { offsetof(_D, _A_base) - offsetof(_D_Self, _C_base) };

void _D_ctor(_D_Self* p, bool b)
{
    if(b)
    {
        p->_B_base._vbtable = _D_vbtable1;
        p->_C_base._vbtable = _D_vbtable2;
    }
    _B_ctor(&p->_B_base, false);
    _C_ctor(&p->_C_base, false);
}

int main()
{
    // D d;
    _D d;
    _D_ctor(&d._self, true);

    // C* pc;
    _C_Self* pc = &d._self._C_base;
    // pc->a = 0;
    ((_A*)((char*)pc + pc->_vbtable[0]))->a = 0;

    // C* pb;
    _B_Self* pb = &d._self._B_base;
    // pb->a = 1;
    ((_A*)((char*)pb + pb->_vbtable[0]))->a = 1;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.