Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 15:06     Концептуальная задача по ООП (виртуальное наследование в C++) #1
Добрый день.

Есть базовый класс 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;
<<< Вот это не работает.

Я понимаю почему так нельзя.
Вопрос в том, как выйти из положения.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.12.2013, 15:06     Концептуальная задача по ООП (виртуальное наследование в C++)
Посмотрите здесь:

ООП Полиморфизм Наследование C++
Может ли виртуальное наследование быть одиночным? C++
C++ Виртуальное наследование
C++ Виртуальное наследование (указатель на базовый класс)
Не могу понять виртуальное наследование C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
06.12.2013, 15:10     Концептуальная задача по ООП (виртуальное наследование в C++) #2
Цитата Сообщение от lanakramoleb Посмотреть сообщение
В коде есть момент:
if(...)
(B *)&A->method;
else
(D *)&A->method; <<< Вот это не работает.
Логика какая за этим стоит?
И конструторы таки не наследуются.
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 15:20  [ТС]     Концептуальная задача по ООП (виртуальное наследование в C++) #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 виртуально.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
06.12.2013, 15:23     Концептуальная задача по ООП (виртуальное наследование в C++) #4
lanakramoleb, так откуда этот код вызывается? Из нутри класса D?
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 15:25  [ТС]     Концептуальная задача по ООП (виртуальное наследование в C++) #5
Просто из функции
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
06.12.2013, 15:28     Концептуальная задача по ООП (виртуальное наследование в C++) #6
lanakramoleb, ну, если у тебя есть указатель D * ptr, то
C++
1
2
3
4
5
if (/* ... */) {
   ptr->B::method();
} else {
   ptr->D::method();
}
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 15:32  [ТС]     Концептуальная задача по ООП (виртуальное наследование в C++) #7
Указатель A * ptr
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
06.12.2013, 15:38     Концептуальная задача по ООП (виртуальное наследование в C++) #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();
}
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 15:39  [ТС]     Концептуальная задача по ООП (виртуальное наследование в C++) #9
то есть как-то так:


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

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


edited: ой, опоздал....
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
06.12.2013, 15:47     Концептуальная задача по ООП (виртуальное наследование в C++) #10
Есть ещё форма dynamic_cast с указателем, там не бросается исключение при неудачном касте, а возвращается нулевой указатель.

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

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

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

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

Что-то я уже совсем под вечер пятницы не соображаю...
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
06.12.2013, 16:39     Концептуальная задача по ООП (виртуальное наследование в C++) #16
Цитата Сообщение от lanakramoleb Посмотреть сообщение
Точнее, всё гораздо сложнее. Сам метод описан только в B, а уже из него должен вызывается метод, который в B и D разный. Но вызывается всегда из B.
Мда...) Определение метода можно увидеть?
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 16:46  [ТС]     Концептуальная задача по ООП (виртуальное наследование в C++) #17
Которого?
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
06.12.2013, 16:48     Концептуальная задача по ООП (виртуальное наследование в C++) #18
Цитата Сообщение от lanakramoleb Посмотреть сообщение
Которого?
Тот, что описан в B и вызывает другие.
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
06.12.2013, 17:08  [ТС]     Концептуальная задача по ООП (виртуальное наследование в C++) #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)
{
    /* ... */
}
.
.
.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.12.2013, 17:20     Концептуальная задача по ООП (виртуальное наследование в C++)
Еще ссылки по теме:

Виртуальное наследование C++
Виртуальное наследование C++
Для чего нужны виртуальные функции и виртуальное наследование ? C++

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

Или воспользуйтесь поиском по форуму:
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
06.12.2013, 17:20     Концептуальная задача по ООП (виртуальное наследование в C++) #20
lanakramoleb, :/ виртуальные методы же http://ideone.com/1P7JmZ
Yandex
Объявления
06.12.2013, 17:20     Концептуальная задача по ООП (виртуальное наследование в C++)
Ответ Создать тему
Опции темы

Текущее время: 14:22. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru