Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
#1

Концептуальная задача по ООП (виртуальное наследование в C++)

06.12.2013, 15:06. Просмотров 1178. Ответов 20
Метки нет (Все метки)

Добрый день.

Есть базовый класс A.
От него наследуется B : public A.
От B виртуально наследуется C : public virtual B.
Далее D : public C. В C есть множество реализованных методов, которые нужны в D.

Однако конструктор для D нужно наследовать от B, потому-то C от B наследуется виртуально.
Метод method определён в классе B и переопределён для класса D.

В коде есть момент:
if(...)
(B *)&A->method;
else
(D *)&A->method;
<<< Вот это не работает.

Я понимаю почему так нельзя.
Вопрос в том, как выйти из положения.

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.12.2013, 15:06
Ответы с готовыми решениями:

Виртуальное наследование
Ребят, кто - нибуть может на простом примере показать, накой нужно виртуальное...

Виртуальное наследование
Здравствуйте, объясните как реализовано(внутри)под капотом виртуальное...

Виртуальное наследование
Вопрос возник. Собственно, теоретически для чего используется виртуальное...

Виртуальное наследование
В данном коде возникает проблема при создании класса Man_Warrior,а именно при...

Виртуальное наследование
Образно говоря: Class A { private: ... public: virtual void f() {...} } ...

20
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
06.12.2013, 15:10 #2
Цитата Сообщение от lanakramoleb Посмотреть сообщение
В коде есть момент:
if(...)
(B *)&A->method;
else
(D *)&A->method; <<< Вот это не работает.
Логика какая за этим стоит?
И конструторы таки не наследуются.
0
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 15:20  [ТС] #3
Логика в том, что в зависимости от ситуации (разные файловые системы) нужно выполнить разные операции на данными, общими для всех классов.

Про конструкторы... я имел в виду что-то типа:
C++
1
2
3
4
A::A(a, b) {};
B::B(a, b) : A(a, b) {};
C::C(a, b, c) : B(a, b) {...};
D::D(a, b, c) : B(a, b) {...};
То, что в конструкторе D вызывается конструктор B, а не C, и вынуждает наследовать C от B виртуально.
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
06.12.2013, 15:23 #4
lanakramoleb, так откуда этот код вызывается? Из нутри класса D?
0
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 15:25  [ТС] #5
Просто из функции
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
06.12.2013, 15:28 #6
lanakramoleb, ну, если у тебя есть указатель D * ptr, то
C++
1
2
3
4
5
if (/* ... */) {
   ptr->B::method();
} else {
   ptr->D::method();
}
0
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 15:32  [ТС] #7
Указатель A * ptr
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
06.12.2013, 15:38 #8
lanakramoleb, тогда нужно сначло приведение вниз по иерархии (dynamic_cast)
C++
1
2
3
4
5
6
7
if (/* ... */) {
   B & ref = dynamic_cast<B &>(*ptr);   // throws std::bad_cast
   ref.method();
} else {
   D & ref = dynamic_cast<D &>(*ptr);   // throws std::bad_cast
   ref.method();
}
0
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 15:39  [ТС] #9
то есть как-то так:


A * ptr = /*...*/;

if(...)
(B *)ptr->method;
else
(D *)ptr->method;


edited: ой, опоздал....
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
06.12.2013, 15:47 #10
Есть ещё форма dynamic_cast с указателем, там не бросается исключение при неудачном касте, а возвращается нулевой указатель.

Добавлено через 1 минуту
Не ну можно конечно и Сишное приведение, если точно знаешь, что неудачного каста не будет:
C++
1
2
3
4
5
6
A * ptr = /*...*/;
 
if(...)
((B *)ptr)->method();
else
((D *)ptr)->method();
Добавлено через 6 минут
Вообще у меня есть ощущение, что тебе нужен visitor; если нужны такие приведения, то, скорее всего, ты что-то делаешь не так...
0
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 15:51  [ТС] #11
Спасибо, работает.

Правда, с cast'ами не хотелось связываться.

А вот второй вариант не работает. Так изначально и было.
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
06.12.2013, 16:09 #12
lanakramoleb, в общем случае, если нужно понижающее приведение в иерархии, то нужен dynamic_cast.
0
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 16:25  [ТС] #13
Насчёт "что-то делю не так". Согласен. Можно было изначально по-другому.
Но я только дописываю новый функционал.

Добавлено через 10 минут
Погорячился я.
Не помогает.
В обоих случаях вызывается метод из B-класса....
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
06.12.2013, 16:33 #14
Цитата Сообщение от lanakramoleb Посмотреть сообщение
В обоих случаях вызывается метод из B-класса....
Хэх, у меня едиственная идея: method не переопределён в D.
0
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 16:35  [ТС] #15
Точнее, всё гораздо сложнее. Сам метод описан только в B, а уже из него должен вызывается метод, который в B и D разный. Но вызывается всегда из B.

Что-то я уже совсем под вечер пятницы не соображаю...
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
06.12.2013, 16:39 #16
Цитата Сообщение от lanakramoleb Посмотреть сообщение
Точнее, всё гораздо сложнее. Сам метод описан только в B, а уже из него должен вызывается метод, который в B и D разный. Но вызывается всегда из B.
Мда...) Определение метода можно увидеть?
0
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 16:46  [ТС] #17
Которого?
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
06.12.2013, 16:48 #18
Цитата Сообщение от lanakramoleb Посмотреть сообщение
Которого?
Тот, что описан в B и вызывает другие.
0
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 17:08  [ТС] #19
ничего в нём особенного... метод как метод )
смысл такой:

project.h:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
.
.
.
class A
{
/* ... */
}
.
.
.
class B : public A
{
    /* ... */
    int method1(int x);
    int method2(int y);
    /* ... */
}
.
.
.
class C : public virtual B
{
    /* ... */
}
.
.
.
class D : public B
{
    /* ... */
    int method2(int y);
    /* ... */
}
.
.
.
project.cpp:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.
.
.
int B::method1(int x)
{
    /* ... */
    z = method2(k);
    /* ... */
}
int B::method2(int y)
{
    /* ... */
}
.
.
.
int D::method2(int y)
{
    /* ... */
}
.
.
.
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
06.12.2013, 17:20 #20
lanakramoleb, :/ виртуальные методы же http://ideone.com/1P7JmZ
1
06.12.2013, 17:20
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.12.2013, 17:20

Виртуальное наследование и полиморфизм
Читая книгу столкнулся с такой типа такой, что полиморфизм это механизм в...

Не могу понять виртуальное наследование
Непонятны несколько моментов. Как строятся таблицы виртуальных классов? Есть...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru