Форум программистов, компьютерный форум, киберфорум
ООП и паттерны
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.69/13: Рейтинг темы: голосов - 13, средняя оценка - 4.69
 Аватар для vab9petryk
2 / 2 / 1
Регистрация: 28.09.2013
Сообщений: 255

Наследование vs Композиция класса контейнера

04.03.2016, 15:59. Показов 2618. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Мне нужно хранить данные в списке - QList <int>.
И вот не могу понять, что же лучше, унаследоваться от класса QList <int> и добавить нужные мне конструкторы и методы, либо же использовать агрегацию.
Почему я боюсь агрегации? Потому что потом мне нужно будет опять определять операторы, функции аналогичные определениям операторов и функций в классе QList, то есть делать обертку для функций класса QList. Либо же делать QList в моем классе как public.
Почему я боюсь наследование? Я просто не уверен что это является хорошим решением, поэтому и боюсь наследоваться от шаблонного последовательно контейнера.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.03.2016, 15:59
Ответы с готовыми решениями:

Наследование и композиция
Добрый день. Помогите, пожалуйста, разобраться в приведенном примере. #include &lt;iostream&gt; #include &lt;fstream&gt; using...

Наследование и Композиция
Много раз слышал о том, что Композиция почти всегда лучше Наследования. Так вот у меня такой вопрос -- Как же узнать ту самую ситуацию,...

Наследование, композиция и агрегация
#include &lt;iostream&gt; #include &lt;string&gt; #include &lt;vector&gt; using namespace std; class A { public: A() { cout&lt;&lt;&quot;Of A +&quot;&lt;&lt;...

20
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,765
04.03.2016, 22:11
Цитата Сообщение от vab9petryk Посмотреть сообщение
Мне нужно хранить данные в списке - QList <int>.
А я не могу понять, зачем тебе вообще наследование или композиция? Хочешь хранить — храни.
1
 Аватар для vab9petryk
2 / 2 / 1
Регистрация: 28.09.2013
Сообщений: 255
05.03.2016, 10:08  [ТС]
вопрос в том, где хранить QList <int>. Если хранить в классе моем, то это композиция, и я уже назвал почему она мне не нравится. Если унаследоваться от QList <int>, и хранить в унаследованном классе, то это уже насследование
0
Кандёхаем веселее!
 Аватар для MLPMan
296 / 330 / 76
Регистрация: 02.10.2012
Сообщений: 2,175
05.03.2016, 12:17
vab9petryk, в том смысле, что может быть и не нужно определять новый тип.
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
05.03.2016, 13:24
vab9petryk,
Вы расскажите, что Вам надо.
Вам нужен контейнер и QList<int> Вас не устраивает, поэтому Вы хотите написать свой контейнер? Чем не устраивает? Какой интерфейс будет у Вашего контейнера?
0
 Аватар для vab9petryk
2 / 2 / 1
Регистрация: 28.09.2013
Сообщений: 255
05.03.2016, 14:30  [ТС]
Цитата Сообщение от Shamil1 Посмотреть сообщение
Вы расскажите, что Вам надо.
Вам нужен контейнер и QList<int> Вас не устраивает, поэтому Вы хотите написать свой контейнер? Чем не устраивает? Какой интерфейс будет у Вашего контейнера?
Надо хранить int в списке. Но кроме хранения, нужны и дополнительные функции обработки хранящихся элементов, то есть функции, которые будут что-то считать, и возвращать значение. Если бы на этом закончилось, то было бы хорошо, можно было бы спокойно использовать композицию, но нужно также иметь непосредственный доступ к QList <int> из вне. Можно в принципе написать геттер, но тогда каждый раз когда нужно получить какой то элемент списка, надо вызывать геттер. Можно сделать обертку для функций списка, типа at(), first(), last(). Но я еще не определился, какие методы списка мне окончательно нужно использовать из вне.
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
05.03.2016, 14:50
Цитата Сообщение от vab9petryk Посмотреть сообщение
Надо хранить int в списке. Но кроме хранения, нужны и дополнительные функции обработки хранящихся элементов, то есть функции, которые будут что-то считать, и возвращать значение.
Хранить int в списке нужно в каждой второй программе, если не чаще. Это не повод наследовать все эти классы от списка.
Насколько я понял по второму предложению, по сути Ваш класс не является контейнером. (Напрасно Вы рассчитываете на мои телепатические способности. Но я бросил монетку, выпал орёл - значит точно не контейнер). Поэтому нет смысла наследовать его от контейнера.

Цитата Сообщение от vab9petryk Посмотреть сообщение
но нужно также иметь непосредственный доступ к QList <int> из вне
Если нужно - дайте. Добавьте один геттер, возвращающий ссылку на QList.
0
306 / 101 / 18
Регистрация: 04.07.2014
Сообщений: 571
05.03.2016, 17:50
vab9petryk
Во-первых, наследование от классов уровня инфраструктуры не должно происходить. Воспринимайте их как final.

Во-вторых, если сущность выдаёт внутренние данные наружу, то любая функция над этими данными может и должна быть вынесена за пределы этой сущности. Проще говоря, если класс A агрегирует список, а потом просто всем раздаёт элементы списка, то зачем нужен A? Используйте список!

По предоставленному описанию получается, что задача в принципе не имеет смысла.
1
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
30.03.2016, 01:05
Цитата Сообщение от mporro Посмотреть сообщение
Во-первых, наследование от классов уровня инфраструктуры не должно происходить
Бред. Например нужна строка умеющая писаться/читаться в поток/из потока. наиболее удобное решение:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class StreamableString : public AnsiString {
public:
    void LoadFromStream(TStream* Stream) {
        int Cnt;
        Stream->Read(&Cnt, sizeof(Cnt));
        SetLength(Cnt);
        Stream->Read(c_str(), Cnt);
    };
 
    void SaveToStream(TStream* Stream) {
        int Cnt = Length();
        Stream->Write(&Cnt, sizeof(Cnt));
        Stream->Write(c_str(), Cnt);
    };
};
Добавлено через 3 минуты
Цитата Сообщение от vab9petryk Посмотреть сообщение
И вот не могу понять, что же лучше, унаследоваться от класса QList <int> и добавить нужные мне конструкторы и методы, либо же использовать агрегацию.
Тут вопрос просто решается. Все ли методы QList должны быть доступны извне вашего класса? если все то наследовать. Если не все то композиция и оборачивание нужных. Как вариант вместо оборачивания приватное наследование и вынесение в public нужных методов.
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
30.03.2016, 01:50
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Бред. Например нужна строка умеющая писаться/читаться в поток/из потока. наиболее удобное решение:
Зачем может понадобится такая строка? Чем это может быть лучше стандартного:
C#
1
string str = stream1.ReadToEnd();
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
30.03.2016, 02:34
Цитата Сообщение от Shamil1 Посмотреть сообщение
Зачем может понадобится такая строка? Чем это может быть лучше стандартного:
Например для вот такого:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct TVariable {
    TVariableSignature Signature;
    StreamableString FName;
    AnsiString UnmangledName;
    mutable unsigned ScopeId;
 
//.......
    void SaveToStream(TStream *Stream) {
        Signature.SaveToStream(Stream);
        FName.SaveToStream(Stream);
        Stream->Write(&ScopeId, sizeof(ScopeId));
    };
 
    void LoadFromStream(TStream *Stream) {
        Signature.LoadFromStream(Stream);
        FName.LoadFromStream(Stream);
        Stream->Read(&ScopeId, sizeof(ScopeId));
        UnmangleName();
    };
т.е. для чтения сохранения вместе с другими бинарными данными

Добавлено через 5 минут
Цитата Сообщение от vab9petryk Посмотреть сообщение
Можно в принципе написать геттер, но тогда каждый раз когда нужно получить какой то элемент списка, надо вызывать геттер.
можно в принципе написать inline геттер. т.е. он как бы обозначен а как бы в скомпилированном коде его нет. а вообще лучший способ решения такого вопроса - __property которая просто указывает что это поле доступно для чтения извне, а для записи нет. в MSVC они правда тоже только через public геттер из private или protected читать будут. Да и коммитет никак со стандартизацией пропертей не соберется хотя уже 20 лет как назрело.
0
30.03.2016, 06:11

Не по теме:

Fulcrum_013
Ваши знания ООП настолько удручающие, что не о чем даже дискутировать.
Хотя в плане инфраструктуры глупость в архитектуре и в Java есть.

0
30.03.2016, 06:58

Не по теме:

Цитата Сообщение от mporro Посмотреть сообщение
Fulcrum_013
Ваши знания ООП настолько удручающие, что не о чем даже дискутировать.
Хотя в плане инфраструктуры глупость в архитектуре и в Java есть.
Ну и STL это одна большая глупость. А моих знаний ООП мне как то хватает.

0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
30.03.2016, 17:10
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
т.е. для чтения сохранения вместе с другими бинарными данными
Всё равно не понятно, зачем метод LoadFromStream запихивать в класс строки. "можно сделать так" - не аргумент, так не понятно, зачем делать так. Почему не использовать функцию ("внеклассовую")? Или не запихнуть её в класс потока?

Я не вижу тут ни одного преимущества. Зато недостатки я вижу (как передавать TVariable , в какой модуль поместить класс StreamableString и т.д.).
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
30.03.2016, 17:35
Цитата Сообщение от Shamil1 Посмотреть сообщение
Или не запихнуть её в класс потока?
Потому что вариантов сохранения строки может быть много.
Цитата Сообщение от Shamil1 Посмотреть сообщение
Почему не использовать функцию ("внеклассовую")
По той же причине.
Цитата Сообщение от Shamil1 Посмотреть сообщение
в какой модуль поместить класс StreamableString
Конкретно здесь - в том модуле который все это пользует.
Цитата Сообщение от Shamil1 Посмотреть сообщение
Как передавать TVariable
Уточните что и куда передавать? И в чем проблемы с передачей?
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
30.03.2016, 18:50
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Уточните что и куда передавать? И в чем проблемы с передачей?
Программа состоит из модулей. Эти модули обмениваются информацией. Чтобы передать экземпляр объекта TVariable из модуля А в модуль Б, мне придётся отобразить его на другой объект, не использующий StreamableString. Либо добавлять в модуль Б зависимость на ненужные ему классы (и возникает следующий вопрос - каким образом это сделать?).

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Потому что вариантов сохранения строки может быть много.
Много - это сколько? 10? Зачем использовать много разных строк в одном проекте? Дополнительные проблемы ради чего?
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
30.03.2016, 19:04
Цитата Сообщение от Shamil1 Посмотреть сообщение
Либо добавлять в модуль Б зависимость на ненужные ему классы (и возникает следующий вопрос - каким образом это сделать?)
Через приведение к базовому AnsiString

Добавлено через 11 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Зачем использовать много разных строк в одном проекте?
А если не в одном? А если в одном формате файла буфера переменной длины а в другом фиксированной?
Цитата Сообщение от Shamil1 Посмотреть сообщение
Много - это сколько? 10? Зачем использовать много разных строк в одном проекте?
Конкретно в этом проекте пользуется именно этот вариант. Поэтому от строки породился потомок с нужным вариантом сохранения/записи.
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
30.03.2016, 23:33
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Через приведение к базовому AnsiString
Не понял. Как Вы собираетесь передать TVariable через приведение к AnsiString? По-моему, Вам понадобится ещё один класс TVariable2 и явный код, приводящий TVariable к TVariable2.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Поэтому от строки породился потомок с нужным вариантом сохранения/записи.
Вероятно, у Вас есть файл с кодом класса StreamableString. Чем хуже вместо кода класса в этот файл написать код функции? (Предположу, что это как-то связано с тем, как написан класс AnsiString. Кстати, что это за класс?)

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А если в одном формате файла буфера переменной длины а в другом фиксированной?
Вместо двух разных классов использовать две разных функции?
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
31.03.2016, 01:36
Цитата Сообщение от Shamil1 Посмотреть сообщение
Не понял. Как Вы собираетесь передать TVariable через приведение к AnsiString? По-моему, Вам понадобится ещё один класс TVariable2 и явный код, приводящий TVariable к TVariable2.
Тьфу ты блин TVariable. Я прочитал как сам стринг передавать. TVariable это просто один из пользователей этой строки. Прекрасно эти строчки как и сами TVariable запихиваются в массивы которым подобное же сохранение прикручено, прекрасно пишутся в файл и прекрасно читаются. И какая принциальная разница с функцией кроме того что аргумент this придется передавать в функцию явно а не неявно? А разница такая что если этим строчечкам понадобится помнить какая как сохраняется достаточно им эти Save/Load сделать виртуальными. А вот с функциями придется с бубном поплясать.

Добавлено через 13 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Кстати, что это за класс
Строка стандартизированная по отраслевому стандарту ANSI.
Цитата Сообщение от Shamil1 Посмотреть сообщение
Предположу, что это как-то связано с тем, как написан класс AnsiString
Хорошо написан. с одной стороны ведет себя абсолютно так же как char* с другой рефкаунтинг ресайз и полный набор удобств типа Trim UpperCase/LowerCase SubString и т.д. и тп.
Цитата Сообщение от Shamil1 Посмотреть сообщение
По-моему, Вам понадобится ещё один класс TVariable2 и явный код, приводящий TVariable к TVariable2.
ну если понадобится то будет так:
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
template <class StringType>
struct TVariable {
    TVariableSignature Signature;
    StringType FName;
    AnsiString UnmangledName;
    mutable unsigned ScopeId;
    template <class RightType>
    TVariable& operator = (const TVariable<RightType>& Right ){
                   Signature=Right.Signature;
                   UnmangledName=Right.UnmangledName;
                   FName=Right.FName;
                   ScopeId=Right.ScopeId;
    }
//.......
    void SaveToStream(TStream *Stream) {
        Signature.SaveToStream(Stream);
        FName.SaveToStream(Stream);
        Stream->Write(&ScopeId, sizeof(ScopeId));
    };
 
    void LoadFromStream(TStream *Stream) {
        Signature.LoadFromStream(Stream);
        FName.LoadFromStream(Stream);
        Stream->Read(&ScopeId, sizeof(ScopeId));
        UnmangleName();
    };
};
И будет все прекрасно для любого количества типов.

Добавлено через 16 минут
С другой стороны можно конечно породиться от TStream и переопределить его методы записи строки которые по определению виртуальные. Но в каком классе (строки или стрима) в случае чего плодить набор потомков в конечном итоге зависит от того могут ли в одном файле быть строки сохраненные в разных форматах.
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
01.04.2016, 16:48
Представьте:
Есть модуль А (отвечает в том числе за загрузку/сохранение TVariable) и модуль Б (отвечает в том числе за вывод TVariable на экран). Мы загружаем TVariable в модуле А, передаём её в модуль Б, изменяем её (значения свойств) в модуле Б, передаём обратно в модуль А и сохраняем.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А разница такая что если этим строчечкам понадобится помнить какая как сохраняется достаточно им эти Save/Load сделать виртуальными. А вот с функциями придется с бубном поплясать.
У Вас есть код, который создаёт эти "строчечки". Он как-то определяет, экземпляр какого класса создавать. В моём варианте такой же код определяет, какую функцию вызвать для считывания.
Когда Вы получите TVariable<AnsiString>, Вам понадобиться как-то определить, к какому классу (с каким StringType) его приводить. В моём варианте такой же код определяет, какую функцию вызвать для сохранения.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
ну если понадобится то будет так:
Про это я и писал выше. Вам понадобился специальный код для отображения ("маппинга"):
TVariable& operator = (const TVariable<RightType>& Right )
В моём варианте этот код не нужен. Пользы от него я не вижу, а проблемы есть. Самые очевидные:
1. Время на написание кода. Свойств может быть 20+, а подобных объектов (с разными свойствами) в проекте может быть 100+.
2. Если я меняю одно свойство, то нужно не забыть поправить этот маппинг.

Я не понимаю, ради чего таки жертвы. Вы так и не привели ни одного преимущества Вашего подхода (а ля "умная строка").
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.04.2016, 16:48
Помогаю со студенческими работами здесь

Наследование и композиция: фигура, круг
Получил вот такое задание Наследование и композиция. Фигура, координата, цвет, линия, фон, заголовок, круг. Общее: 1....

Очень срочно , через 2 дня сдача) (композиция, наследование)
ребята, сделайте пожалуйста код как можно стандартнее)) спасибо)

Наследование контейнера
А можно ли создать класс, который будет наследовать все функции от vector'a, и собрать его в dll, чтобы подключить на C#?

Наследование vs Композиция vs Агрегация: что лучше выбрать? Как лучше передавать объекты в функции?
Добрый день!! Дело вот в чём, я хочу создать класс, внутри которого будут созданы объекты других классов (реализованных в некоторой...

Выяснить, что представляют из себя отношения Ф композиция Ф и Ф композиция Ф^{-1}
Добрый день. До этого у меня было такое задание: Выяснить, какими из свойств: рефлексивность, антирефлексивность, симметричность,...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru