2017-02-07 22 views
0

Я понимаю эффект из виртуального наследования в алмазе наследование дерева, но не побочные эффекты (если таковой имеется) в неалмазном наследстве дерево.виртуального наследования в дереве неалмазного наследства - память и поведение побочных эффекты

Если вы просто

class A; 

class B: public virtual A; 

Какие различия существуют в поведении или макете памяти (если таковые имеются) из этих двух классов, т.е. порядка вызова конструктора и т.д.

Предположим class A имеет членов данных.

Просьба предоставить официальную документацию для ответа

+0

Он работает так же, если у вас есть бриллиант или нет. – NathanOliver

+1

Я сомневаюсь, что в стандарте будут указаны детали реализации. AFAIK, вам даже не нужно использовать vtable (хотя большинство из них). – OMGtechy

+0

@NathanOliver Каково поведение в моем примере? – Adrian

ответ

2

Один эффект виртуального наследования является то, что понижающее приведение по static_cast не работает. Если вы хотите отказаться от виртуальной базы, вместо этого вы должны использовать dynamic_cast.

A* pa = new B; 
B* pb1 = static_cast<B*>(pa); // doesn't work: compilation error 
B* pb2 = dynamic_cast<B*>(pa); // works 

Цитируется по стандарту (5.2.9):

prvalue типа «указатель на CV1 B», где В представляет собой тип класса, может быть преобразован в prvalue типа «указатель в CV2 D»... если ... B не является ни виртуальный базовый класс D, ни базовый класс виртуального базового класса D.

+0

Да! Это та информация, которую я искал. – Adrian

0

Что касается раскладки памяти, некоторые компиляторы могли бы поместить данные виртуальной базы после элементы данных подкласса (см Multiple Inheritance Considered Useful):

class A { 
public: 
    int a; 
}; 

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

int main() { 
    B b; 

    std::cout << "&b.a < &b.b = " << (&(b.a) < &(b.b)) << std::endl; // &b.a < &b.b = = 0 

    return 0; 
} 

На данных членов другой стороны, Невиртуальные Базы обычно помещаются перед тем членам данных ребенка:

class A { 
public: 
    int a; 
}; 

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

int main() { 
    B b; 

    std::cout << "&b.a < &b.b = " << (&(b.a) < &(b.b)) << std::endl; // &b.a < &b.b = 1 

    return 0; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^