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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
lanakramoleb
1 / 1 / 0
Регистрация: 18.09.2012
Сообщений: 32
#1

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

06.12.2013, 15:06. Просмотров 1011. Ответов 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
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Концептуальная задача по ООП (виртуальное наследование в C++) (C++):

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

Виртуальное наследование - C++
Здравствуйте, объясните как реализовано(внутри)под капотом виртуальное наследование? Например виртуальные методы реализованы через...

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

Виртуальное наследование - C++
Ребят, кто - нибуть может на простом примере показать, накой нужно виртуальное наследование классов (class B : public virtual A) ?

Не могу понять виртуальное наследование - C++
Непонятны несколько моментов. Как строятся таблицы виртуальных классов? Есть базовый класс, У него два предка. А еще есть третий...

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

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
gray_fox
What a waste!
1520 / 1223 / 70
Регистрация: 21.04.2012
Сообщений: 2,560
Завершенные тесты: 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!
1520 / 1223 / 70
Регистрация: 21.04.2012
Сообщений: 2,560
Завершенные тесты: 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!
1520 / 1223 / 70
Регистрация: 21.04.2012
Сообщений: 2,560
Завершенные тесты: 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!
1520 / 1223 / 70
Регистрация: 21.04.2012
Сообщений: 2,560
Завершенные тесты: 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!
1520 / 1223 / 70
Регистрация: 21.04.2012
Сообщений: 2,560
Завершенные тесты: 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!
1520 / 1223 / 70
Регистрация: 21.04.2012
Сообщений: 2,560
Завершенные тесты: 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!
1520 / 1223 / 70
Регистрация: 21.04.2012
Сообщений: 2,560
Завершенные тесты: 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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.12.2013, 16:35
Привет! Вот еще темы с ответами:

Может ли виртуальное наследование быть одиночным? - C++
виртуальное наследование это множественное наследование, при котором нескольким классам, имеющим один базовый всегда сопоставляется один...

Для чего нужны виртуальные функции и виртуальное наследование ? - C++
Для чего нужны виртуальные функции и виртуальное наследование ? Я нашел не сколько статей но не все понял. Заранее спасибо!

ООП.Наследование - C++
Здравствуйте.Помогите отредактировать код. Прикрепил скрин задания(Вверху,то как примерно должно получиться решение,ниже само задание). Не...

ООП и наследование - C++
Доброго времени суток, форумчане. Столкнулся с такой непонятной ситуацией. Есть класс А class A { private: int i=1; public: ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
06.12.2013, 16:35
Ответ Создать тему
Опции темы

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