// Example program#include <iostream>
#include <string>
using namespace std;
class A
{
public:
int a;
};
class B: public A
{
public:
int b;
};
class C: public A
{
public:
int c;
};
class D: public B, public C
{
public:
int d;
};
void f1(B* b)
{
cout<<b->b<<" "<<b->a<<endl;
cout<<b<<endl;
}
void f2(C* c)
{
cout<<c->c<<" "<<c->a<<endl;
cout<<c<<endl;
}
int main()
{
D d;
d.c = 1;
d.b = 2;
d.C::a = 3;
d.B::a = 4;
cout<<&d<<endl;
f1(&d);
f2(&d);
}
Здравствуйте, const_volatile, Вы писали:
_>google://diamond inheritance
Ok, давайте без ромба — суть вопроса тут не в ромбе, а в адресах:
// Example program#include <iostream>
#include <string>
using namespace std;
class B
{
public:
int b;
};
class C
{
public:
int c;
};
class D: public B, public C
{
public:
int d;
};
void f1(B* b)
{
cout<<b->b<<endl;
cout<<b<<endl;
}
void f2(C* c)
{
cout<<c->c<<endl;
cout<<c<<endl;
}
int main()
{
D d;
d.c = 1;
d.b = 2;
cout<<&d<<endl;
f1(&d);
f2(&d);
}
Почему мы передаём один и тот же адрес в две функции, а печатаются разные адреса?
Здравствуйте, RiNSpy, Вы писали:
RNS>Здравствуйте, const_volatile, Вы писали:
_>>google://diamond inheritance
RNS>Ok, давайте без ромба — суть вопроса тут не в ромбе, а в адресах:
RNS>Почему мы передаём один и тот же адрес в две функции, а печатаются разные адреса?
потому что мы в функции передаем не один и тот же адрес
объяви в main переменные C* и B*, проинициализируй их адресом d и выведи в cout;
подумай, почему все так.
Здравствуйте, RiNSpy, Вы писали:
RNS>Почему мы передаём один и тот же адрес в две функции, а печатаются разные адреса?
вот выхлоп на ваш исходный код: http://ideone.com/Wtmifr
мы передаем не просто адреса, а передаем указатель на класс, а функция в свою очередь принимает указатель на другой класс. идет преобразование, эквивалентное static_cast, которое учитывает расположение объекта в памяти, и делает необходимые смещения
теперь разберем ваш второй пример ( http://ideone.com/tE1lde ). в нем лейаут объекта будет таким:
D = B | C
размер в данном случае получится таким (хотя и не обязательно так, но в простом примере все просто):
sizeof(D) = sizeof(int) + sizeof(B) + sizeof(C) = sizeof(int) + sizeof(int) + sizeof(int)
Раз разбираем базовые понятия, подкину ещё пять копеек.
Из-за того, что адреса не обязаны совпадать, что мы здесь и видим, нужно пользоваться static_cast, а не reinterpret_cast.
static_cast умеет менять указатель , а reinterpret_cast нет.
Здравствуйте, const_volatile, Вы писали:
_>Здравствуйте, Кодт, Вы писали:
_>>>google://diamond inheritance К>>а где здесь ромб? Две однотипные базы вижу, ромба не вижу.
_>это даймонд-наследование по определению кагбе.
для даймонд-наследования нужна виртуальная база, кагбе.
Здравствуйте, night beast, Вы писали:
_>>>>google://diamond inheritance К>>>а где здесь ромб? Две однотипные базы вижу, ромба не вижу. _>>это даймонд-наследование по определению кагбе. NB>для даймонд-наследования нужна виртуальная база, кагбе.
здрасьте, приплыли. виртуальное множественное наследование было _сделано_, чтобы разрешить противоречие, возникающее при обращении к базовому классу при diamond inheritance. это ортогональные вещи. страуструпа штоле почитайте, глава про multiple inheritance, там это подробно разжёвано.
Здравствуйте, const_volatile, Вы писали:
_>>>>>google://diamond inheritance К>>>>а где здесь ромб? Две однотипные базы вижу, ромба не вижу. _>>>это даймонд-наследование по определению кагбе. NB>>для даймонд-наследования нужна виртуальная база, кагбе.
_>здрасьте, приплыли. виртуальное множественное наследование было _сделано_, чтобы разрешить противоречие, возникающее при обращении к базовому классу при diamond inheritance. это ортогональные вещи. страуструпа штоле почитайте, глава про multiple inheritance, там это подробно разжёвано.
еще раз. где в оригинальном примере вы ромб увидели?
Здравствуйте, night beast, Вы писали:
_>>здрасьте, приплыли. виртуальное множественное наследование было _сделано_, чтобы разрешить противоречие, возникающее при обращении к базовому классу при diamond inheritance. это ортогональные вещи. страуструпа штоле почитайте, глава про multiple inheritance, там это подробно разжёвано.
NB>еще раз. где в оригинальном примере вы ромб увидели?
Ну я тоже ромб вижу:
class A
{
public:
int a;
};
class B: public A
{
public:
int b;
};
class C: public A
{
public:
int c;
};
class D: public B, public C
{
public:
int d;
};
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, Stanislav V. Zudin, Вы писали:
_>>>здрасьте, приплыли. виртуальное множественное наследование было _сделано_, чтобы разрешить противоречие, возникающее при обращении к базовому классу при diamond inheritance. это ортогональные вещи. страуструпа штоле почитайте, глава про multiple inheritance, там это подробно разжёвано.
NB>>еще раз. где в оригинальном примере вы ромб увидели?
SVZ>Ну я тоже ромб вижу:
могу только присоединиться к Кодт " Две однотипные базы вижу, ромба не вижу."
Здравствуйте, night beast, Вы писали:
SVZ>>Ну я тоже ромб вижу:
NB>могу только присоединиться к Кодт " Две однотипные базы вижу, ромба не вижу."
NB>
NB>A A
NB>| |
NB>B C
NB> \ /
NB> D
NB>
Я придерживаюсь терминологии, использованной Мейерсом, да и википедия с ним согласна:
The "diamond problem" (sometimes referred to as the "deadly diamond of death"[4]) is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If there is a method in A that B and C have overridden, and D does not override it, then which version of the method does D inherit: that of B, or that of C?
Здравствуйте, Stanislav V. Zudin, Вы писали:
SVZ>Я придерживаюсь терминологии, использованной Мейерсом, да и википедия с ним согласна:
SVZ>
SVZ>The "diamond problem" (sometimes referred to as the "deadly diamond of death"[4]) is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If there is a method in A that B and C have overridden, and D does not override it, then which version of the method does D inherit: that of B, or that of C?
приведено описание термина "diamond problem", которое к обсуждаемому примеру отношение не имеет.
Здравствуйте, uzhas, Вы писали:
U>могу посоветовать гуглить по "C++ class layout"
когда то делал наглядную отображалку лайаутов для некоторого набора иерархий, в некоторых местах там ошибки, но в общем — посмотреть можно https://www.shtoba.net/cpp/objectLayout/
Здравствуйте, night beast, Вы писали:
NB>могу только присоединиться к Кодт " Две однотипные базы вижу, ромба не вижу."
NB>
NB>A A
NB>| |
NB>B C
NB> \ /
NB> D
NB>
ты нарисовал объекты
а если нарисовать отношения между классами, то получишь ромб
но, очевидно, что вопрос не связан с ромбом, больше связано с множественным наследованием, организации объекта в памяти и системой типов в плюсах