Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 13.05.2014
Сообщений: 2
1

Как сделать хитрое наследование? Хранить в одном контейнере родителя и потомков

13.05.2014, 21:43. Просмотров 1094. Ответов 5
Метки нет (Все метки)


Доброго времени суток!

Интересует, можно ли при создании класса-потомка назначать его родительский класс (не копировать, а именно назначать)?
Поясню, зачем это хотелось бы сделать. Есть класс-контейнер, что-то типа:
C++ (Qt)
1
2
3
4
class Cont{
public:
    std::vector<A> as;
}
Экземпляры класса A конструируются с передачей им определенных параметров, и в зависимости от этого создают экземпляр класса B или C:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class B;
class C;
 
class A{
    A(<params>) { ... }
public:
    // out-interface functions
    virtual void sendMessage(std::string message);
protected:
    // in-interface functions
    void messageWasReceived(std::string message);
private:
    B * b;
    C * c;
    Cont * cont;
}
К примеру, B и C у меня клиент и сервер, что из них создается - зависит от параметров в конструкторе класса A, который является универсальным классом соединения.
Теперь для простоты (а точнее, для красоты кода) я хотел бы, чтобы клиенту и серверу не надо было хранить внутри себя указатель на экземпляр класса более высокого уровня, будь то A или Cont. Для этого я наследую B и C от A:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class B : public A
{
public:
    void sendMessage(std::string message);
private:
    void recvMes(std::string message) { ... messageWasReceived(message);}
}
 
class C : public A
{
public:
    void sendMessage(std::string message);
private:
    void recvMes(std::string message) { ... messageWasReceived(message);}
}
Однако, мои знания о наследовании позволяют мне максимум, что сделать - это скопировать экземпляр класса A, созданного в Cont, в экземпляр класса A, который является предком B или C. При этом, если я напишу в Cont:
C++ (Qt)
1
as[0].sendMessage("txt");
, то не произойдет вызова B::sendMessage или C::sendMessage, чего хотелось бы.

Знает ли кто-нибудь, как при наследовании задать родительский класс по адресу?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.05.2014, 21:43
Ответы с готовыми решениями:

Как хранить объекты разных классов в одном контейнере
Здравствуйте! Хочу реализовать хранение разных классов(базовый и наследник) в одном контейнере....

Как хранить все ресурсы приложения во внешнем файле (контейнере)
Опять подошла к некоему порогу, но есть сильные подозрения что тема очень не нова, но поиском не...

Наследование: как вызвать деструктор родителя?
набросал такой код: class a(): def __del__(self): print u'del-a' # class b(a): def...

Структура представления данных, где у родителя могут существовать более двух потомков
Как представить структуру в виде двоичного дерева, где у родителя могут существовать больше двух...

5
6918 / 5983 / 2710
Регистрация: 14.04.2014
Сообщений: 25,504
13.05.2014, 21:54 2
Мне кажется, ты сначала пытаешься разделить что-то на классы, а потом снова в кучу смешиваешь. Храни в своём контейнере хоть A, хоть его потомков. Конструктор у каждого должен быть свой. А виртуальный sendMessage() будет вызывать по объекту.
0
0 / 0 / 0
Регистрация: 13.05.2014
Сообщений: 2
14.05.2014, 10:26  [ТС] 3
1) Цель - хранить в Cont объекты A. Cont вообще ничего не должен знать о B или C.
2) Да, виртуальный sendMessage() будет вызываться как надо. Но я хочу, чтобы также B и C ничего не знали о Cont. И при получении сообщения из сети вызывали унаследованную функцию класса A.
3) И экземпляр этого класса A хочу чтобы лежал в Cont.

Понятно, что можно написать всяких getAddr в классе A и решить задачу. Но оно получится не так красиво, как при присвоении адреса родительского объекта (A) при создании B и C.
0
Эксперт С++
1663 / 1035 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
14.05.2014, 11:02 4
Я сделал такую штуку под C++11 на основе union, как раз для хранения в контейнерах. Вкратце: параметризуется базовым классом и наследниками (факт наследования и уникальность параметров проверяется статически). Инициализируется конструктором, которому передают указатель на нужный тип-наследник (значение указателя не имеет значения, используется только тип для выбора правильного потомка) и аргументы для создания самого наследника. Неявно преобразуется к ссылке на базовый класс. Если интересно - велкам в личку.
0
6918 / 5983 / 2710
Регистрация: 14.04.2014
Сообщений: 25,504
14.05.2014, 12:54 5
Похоже, я один не понимаю, чего хочет автор.
Если нужно вызывать функцию A из B и C, то зачем объявлять её виртуальной?
Если в списке лежит объект A, то он и есть A. Причём тут B и C?
0
3318 / 2695 / 729
Регистрация: 25.03.2012
Сообщений: 9,735
Записей в блоге: 1
14.05.2014, 13:10 6
nmcf, нас двое
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.05.2014, 13:10

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

В каком STL-контейнере лучше хранить объекты?
Есть класс, реализующий адреса class address { ... } Поискал в сети увидел 3 варианта...


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

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

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