Полиморфизм и адреса
От: RiNSpy  
Дата: 24.01.17 22:00
Оценка:
Что выведет этот код и почему?

// 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);
}
Re: Полиморфизм и адреса
От: const_volatile  
Дата: 24.01.17 22:06
Оценка: +1 -1
google://diamond inheritance
Re: Полиморфизм и адреса
От: antropolog  
Дата: 24.01.17 23:35
Оценка:
Здравствуйте, RiNSpy, Вы писали:

RNS>Что выведет этот код и почему?


аккуратней, за подобные вопросы на собесе может и в щщи прилететь.
Re: Полиморфизм и адреса
От: night beast СССР  
Дата: 25.01.17 06:20
Оценка:
Здравствуйте, RiNSpy, Вы писали:

RNS>Что выведет этот код и почему?


в чем проблема то?
Re[2]: Полиморфизм и адреса
От: Кодт Россия  
Дата: 25.01.17 09:27
Оценка:
Здравствуйте, const_volatile, Вы писали:

_>google://diamond inheritance


а где здесь ромб? Две однотипные базы вижу, ромба не вижу.

struct X {
  int y;
  int z;
};

X x = {};
x.y = 1;
assert(x.z == 1); // wtf, почему жизнь - боль, ведь типы-то совпадают?
Перекуём баги на фичи!
Re[2]: Полиморфизм и адреса
От: RiNSpy  
Дата: 25.01.17 10:37
Оценка:
Здравствуйте, 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);
}


Почему мы передаём один и тот же адрес в две функции, а печатаются разные адреса?
Re[3]: Полиморфизм и адреса
От: night beast СССР  
Дата: 25.01.17 10:42
Оценка:
Здравствуйте, RiNSpy, Вы писали:

RNS>Здравствуйте, const_volatile, Вы писали:


_>>google://diamond inheritance


RNS>Ok, давайте без ромба — суть вопроса тут не в ромбе, а в адресах:


RNS>Почему мы передаём один и тот же адрес в две функции, а печатаются разные адреса?


потому что мы в функции передаем не один и тот же адрес

объяви в main переменные C* и B*, проинициализируй их адресом d и выведи в cout;
подумай, почему все так.
Re[3]: Полиморфизм и адреса
От: uzhas Ниоткуда  
Дата: 25.01.17 10:48
Оценка: 4 (1)
Здравствуйте, 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)

могу посоветовать гуглить по "C++ class layout"
первая внятная ссылка: http://www.openrce.org/articles/files/jangrayhood.pdf
Отредактировано 25.01.2017 12:57 uzhas . Предыдущая версия .
Re[4]: Полиморфизм и адреса
От: _NN_ www.nemerleweb.com
Дата: 25.01.17 19:07
Оценка: +1
Здравствуйте, uzhas, Вы писали:

Раз разбираем базовые понятия, подкину ещё пять копеек.
Из-за того, что адреса не обязаны совпадать, что мы здесь и видим, нужно пользоваться static_cast, а не reinterpret_cast.

static_cast умеет менять указатель , а reinterpret_cast нет.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Полиморфизм и адреса
От: const_volatile  
Дата: 25.01.17 23:28
Оценка:
Здравствуйте, Кодт, Вы писали:

_>>google://diamond inheritance

К>а где здесь ромб? Две однотипные базы вижу, ромба не вижу.

это даймонд-наследование по определению кагбе.

    A
   / \
  B   C
   \ /
    D

так виднее?

К>
К>struct X {
К>  int y;
К>  int z;
К>};

К>X x = {};
К>x.y = 1;
К>assert(x.z == 1); // wtf, почему жизнь - боль, ведь типы-то совпадают?
К>


это к чему вообще?
Re[4]: Полиморфизм и адреса
От: night beast СССР  
Дата: 26.01.17 06:05
Оценка:
Здравствуйте, const_volatile, Вы писали:

_>Здравствуйте, Кодт, Вы писали:


_>>>google://diamond inheritance

К>>а где здесь ромб? Две однотипные базы вижу, ромба не вижу.

_>это даймонд-наследование по определению кагбе.


для даймонд-наследования нужна виртуальная база, кагбе.
Re[5]: Полиморфизм и адреса
От: const_volatile  
Дата: 26.01.17 06:40
Оценка: +1
Здравствуйте, night beast, Вы писали:

_>>>>google://diamond inheritance

К>>>а где здесь ромб? Две однотипные базы вижу, ромба не вижу.
_>>это даймонд-наследование по определению кагбе.
NB>для даймонд-наследования нужна виртуальная база, кагбе.

здрасьте, приплыли. виртуальное множественное наследование было _сделано_, чтобы разрешить противоречие, возникающее при обращении к базовому классу при diamond inheritance. это ортогональные вещи. страуструпа штоле почитайте, глава про multiple inheritance, там это подробно разжёвано.
Re[6]: Полиморфизм и адреса
От: night beast СССР  
Дата: 26.01.17 06:49
Оценка:
Здравствуйте, const_volatile, Вы писали:

_>>>>>google://diamond inheritance

К>>>>а где здесь ромб? Две однотипные базы вижу, ромба не вижу.
_>>>это даймонд-наследование по определению кагбе.
NB>>для даймонд-наследования нужна виртуальная база, кагбе.

_>здрасьте, приплыли. виртуальное множественное наследование было _сделано_, чтобы разрешить противоречие, возникающее при обращении к базовому классу при diamond inheritance. это ортогональные вещи. страуструпа штоле почитайте, глава про multiple inheritance, там это подробно разжёвано.


еще раз. где в оригинальном примере вы ромб увидели?
Re[7]: Полиморфизм и адреса
От: Stanislav V. Zudin Россия  
Дата: 26.01.17 06:54
Оценка:
Здравствуйте, 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
Re[8]: Полиморфизм и адреса
От: night beast СССР  
Дата: 26.01.17 06:58
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

_>>>здрасьте, приплыли. виртуальное множественное наследование было _сделано_, чтобы разрешить противоречие, возникающее при обращении к базовому классу при diamond inheritance. это ортогональные вещи. страуструпа штоле почитайте, глава про multiple inheritance, там это подробно разжёвано.


NB>>еще раз. где в оригинальном примере вы ромб увидели?


SVZ>Ну я тоже ромб вижу:


могу только присоединиться к Кодт " Две однотипные базы вижу, ромба не вижу."

A   A
|   |
B   C
 \ /
  D
Отредактировано 26.01.2017 7:01 night beast . Предыдущая версия .
Re[9]: Полиморфизм и адреса
От: Stanislav V. Zudin Россия  
Дата: 26.01.17 07:07
Оценка:
Здравствуйте, 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
Re[10]: Полиморфизм и адреса
От: night beast СССР  
Дата: 26.01.17 07:15
Оценка:
Здравствуйте, 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", которое к обсуждаемому примеру отношение не имеет.
Re[4]: Полиморфизм и адреса
От: vopl Россия  
Дата: 26.01.17 07:39
Оценка: 4 (1)
Здравствуйте, uzhas, Вы писали:

U>могу посоветовать гуглить по "C++ class layout"


когда то делал наглядную отображалку лайаутов для некоторого набора иерархий, в некоторых местах там ошибки, но в общем — посмотреть можно
https://www.shtoba.net/cpp/objectLayout/
c++ class layout
Re[9]: Полиморфизм и адреса
От: uzhas Ниоткуда  
Дата: 26.01.17 09:53
Оценка: +1
Здравствуйте, night beast, Вы писали:

NB>могу только присоединиться к Кодт " Две однотипные базы вижу, ромба не вижу."


NB>
NB>A   A
NB>|   |
NB>B   C
NB> \ /
NB>  D
NB>


ты нарисовал объекты
а если нарисовать отношения между классами, то получишь ромб
но, очевидно, что вопрос не связан с ромбом, больше связано с множественным наследованием, организации объекта в памяти и системой типов в плюсах
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.