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

Сложность абстракции, полиморфизм, дублирование и другие - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 4.75
Bers
Заблокирован
25.11.2011, 23:57     Сложность абстракции, полиморфизм, дублирование и другие #1
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
//структура "матрица"
//Представляет собой обёртку над двухмерным массивом
template<typename TypeT, int _SizeX, int _sizeY>
struct Array2D
{
    Array2D()
    {
        for(int y = 0; y < _sizeY; ++y)
        {
            for(int x = 0; x < _SizeX; ++x)
            {
               Arr[x][y] =  rand()%100 + 1;
            }
        }
    }
    TypeT Arr[_SizeX][_sizeY];
};
 
//создаём 100 штук таких матриц
//каждая матрица будит проинициализирована
//случайными числами
Array2D<int,100,100> SuperArray[100];
 
 
int main()
{
   return 0;
};
Добавлено через 5 минут
Цитата Сообщение от silent_1991 Посмотреть сообщение
proger2030, вы читаете, что вам пишут? Используйте трёхмерные массивы (т.е. массивы двухмерных массивов, с логической точки зрения), в самом верхнем цикле перебирая двухмерные массивы, а во вложенных заполняя каждый из них.
Настоятельно не рекомендую использовать трехмерные массивы.
Более того, крайне не рекомендую использовать двухмерные массивы.

Одномерный массив намного проще для понимания, и гибче в управлении.
Его легче трансформировать во всевозможные состояния.

Если так сильно понадобились многомерные массивы - всегда можно инкапсулировать сложность абстракции внутри нового класса.

Массивы массивов намного гибче и проще в плане всевозможных трансформаций/сортировок и тп.
Не придётся голову ломать над глючной адресной арифметикой многомерных массивов.

Всегда нужно стремится понижать сложность архитектуры. Для этого и существуют классы.

 Комментарий модератора 
Корни темы здесь - Как создать 100 массивов разными значениями ?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.11.2011, 23:57     Сложность абстракции, полиморфизм, дублирование и другие
Посмотрите здесь:

C++ Полиморфизм
полиморфизм=( C++
C++ полиморфизм
C++ Чего стоит использование абстракции типов данных?
Полиморфизм. C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
26.11.2011, 00:30     Сложность абстракции, полиморфизм, дублирование и другие #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Bers, если Вы так настоятельно рекомендуете, то за Вас уже давно постарались: есть std::vector, есть std::array. Смысла писать собственный костыль по имени Array2D я не вижу. То есть я настоятельно рекомендую пользоваться классами стандартной библиотеки! Чтобы избежать возникновения вероятных ошибок. Я повторяю, я настоятельно рекомендую!
Bers
Заблокирован
26.11.2011, 00:47  [ТС]     Сложность абстракции, полиморфизм, дублирование и другие #3
Цитата Сообщение от fasked Посмотреть сообщение
Bers, если Вы так настоятельно рекомендуете, то за Вас уже давно постарались: есть std::vector, есть std::array. Смысле писать собственный костыль по имени Array2D я не вижу. То есть я настоятельно рекомендую пользоваться классами стандартной библиотеки! Чтобы избежать возникновения вероятных ошибок. Я повторяю, я настоятельно рекомендую!
Смысл написания "костылей" по имени Array2D - понижение сложности архитектуры.
Очень важно знать как это можно сделать. И знать, когда это нужно применять.

А вот что именно вы там используете в основе новой абстракции - вектор векторов, или собственный велосипед - это уже личное дело каждого, и к идее моей рекомендации отношения не имеет. Я не зря написал "не суть".

Смысл моей идеи прост: "разделяй и властвуй".

А по поводу вектора - оставьте свои рекомендации для новичков. Мне об этом говорить не нужно.
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
26.11.2011, 00:51     Сложность абстракции, полиморфизм, дублирование и другие #4
Цитата Сообщение от Bers Посмотреть сообщение
Смысл написания "костылей" по имени Array2D - понижение сложности архитектуры.
Очень важно знать как это можно сделать. И знать, когда это нужно применять.
Понижая сложность архитектуры, Вы порождаете дублирующий код. Избегая одного зла - производите другое. И это однозначно не выход. Отсюда я позволяю себе сделать вывод о том, что Вы не знаете как делать правильно и когда это необходимо.

Не по теме:

Цитата Сообщение от Bers Посмотреть сообщение
А по поводу вектора - оставьте свои рекомендации для новичков. Мне об этом говорить не нужно.
Вообще я иронизировал на тему Вашей же привычки отпускать рекомендации

Bers
Заблокирован
26.11.2011, 00:59  [ТС]     Сложность абстракции, полиморфизм, дублирование и другие #5
Цитата Сообщение от fasked Посмотреть сообщение
Понижая сложность архитектуры, Вы порождаете дублирующий код.
1. Я не понял про "порождение дублирующего кода". Поясните эту мысль.

2. Между сложностью решения, и дублированием лично я выбираю второе. Пускай будит уйма дублированного кода, вплоть до хардкорной копипасты, если при этом удастся погасить сложность общего решения. Чем проще архитектура, тем она безопаснее. В таком коде всегда меньше всего ошибок. Его проще сопровождать. Он быстрее конструируется.
Самый простой код - продукт продуманной архитектуры. И бла бла бла.

3. Элегантное решение с применением того же самого полиморфизма порождает очень много дублированного кода. Но никого это особо не парит. Что характеризует.
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
26.11.2011, 01:06     Сложность абстракции, полиморфизм, дублирование и другие #6
Цитата Сообщение от Bers Посмотреть сообщение
Я не понял про "порождение дублирующего кода". Поясните эту мысль.
Я уже сказал выше, но да ладно, пусть будет. Вы порождаете сущность, которая дублирует функционал уже существующих сущностей. А именно std::array как минимум. При чем делает это хуже. Я бы еще понял, если бы Вы создали обертку над std::array, но нет же, не вижу такого здесь.
Цитата Сообщение от Bers Посмотреть сообщение
Между сложностью решения, и дублированием лично я выбираю второе. Пускай будит уйма дублированного кода, вплоть до хардкорной копипасты, если при этом удастся погасить сложность общего решения. Чем проще архитектура, тем она безопаснее. В таком коде всегда меньше всего ошибок. Его проще сопровождать. Он быстрее конструируется.
И о чем с Вами прикажете разговаривать после такого, господин Архитектор?
Цитата Сообщение от Bers Посмотреть сообщение
Элегантное решение с применением того же самого полиморфизма порождает очень много дублированного кода. Но никого это особо не парит. Что характеризует.
Где это Вы в полиморфизме дублирование разглядели? Полиморфизм порожден как раз таки устранять дублирование, а не порождать его.
Bers
Заблокирован
26.11.2011, 01:30  [ТС]     Сложность абстракции, полиморфизм, дублирование и другие #7
Цитата Сообщение от fasked Посмотреть сообщение
Вы порождаете сущность, которая дублирует функционал уже существующих сущностей.
Если в проекте присутствует одновременно и вектор, и велосипед, реализующий те же самые услуги - это ещё можно как то называть "дублированием функционала".
Но если в проекте присутствует только велосипед, или только вектор, то ни о каком дублировании уже нет и речи.

Цитата Сообщение от fasked Посмотреть сообщение
Где это Вы в полиморфизме дублирование разглядели? Полиморфизм порожден как раз таки устранять дублирование, а не порождать его.
Примеры дублирования кода:

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
struct A { int a;};
struct B { int a;};  //одна из них явно лишьняя
 
 
class Base
{
public:
    Base(){}
    virtual ~Base(){};
    virtual void View()=0;
};
 
class ConcreteA: public Base
{
public:
                     ConcreteA():Base(){}
    /*virtual */    ~ConcreteA() {}
    /*virtual*/      void View() { std::cout<< "ConcreteA\n";}
};
 
class ConcreteB: public Base
{
public:
                    ConcreteB():Base(){}
    /*virtual */    ~ConcreteB() {}
    /*virtual*/     void View() { std::cout<< "ConcreteB\n";}
};
 
//Самый популярный рецепт изготовления полиморфного семейства:
//1. Написать базовый интерфейс.
//2. Хардкорно копипастить его по всем потомкам.
 
//Причем зачастую, полиморф пользуют везде, где хотят 
//программировать в терминах интерфейсов. 
//даже там, где не требуется воспринимать абсолютно 
//разные типы объектов, как одну и туже сущность.

Хотя, если по задумке не требуется интерпретировать объекты типа ConcreteA и ConcreteB как одну и ту же сущность, то полиморфизм тут вообще не нужен будит. Тем не менее, они дублируют интерфейсы друг друга.
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
26.11.2011, 01:36     Сложность абстракции, полиморфизм, дублирование и другие #8
Цитата Сообщение от Bers Посмотреть сообщение
Если в проекте присутствует одновременно и вектор, и велосипед, реализующий те же самые услуги - это ещё можно как то называть "дублированием функционала".
Как-то?
Цитата Сообщение от Bers Посмотреть сообщение
Но если в проекте присутствует только велосипед, или только вектор, то ни о каком дублировании уже нет и речи.
Я не понимаю, как средства стандартной библиотеки могут не входить в проект. Должны быть серьезные причины и не менее вразумительные обоснования на то, чтобы не пользоваться стандартной библиотекой языка.
Цитата Сообщение от Bers Посмотреть сообщение
Примеры дублирования кода
Кроме как "идиотскими" я эти примеры назвать никак не могу. То есть они показывают технологию полиморфизма как факта и не более. Где здесь полиморфизм с точки зрения красоты решения и архитектуры я не вижу и вряд ли кто-либо вообще видит.
Bers
Заблокирован
26.11.2011, 01:51  [ТС]     Сложность абстракции, полиморфизм, дублирование и другие #9
Цитата Сообщение от fasked Посмотреть сообщение
Я не понимаю, как средства стандартной библиотеки могут не входить в проект.
Ну например, хэш-таблица, смартпоинтеры, аррэй не входят в поставку 2008 студии.

Цитата Сообщение от fasked Посмотреть сообщение
Кроме как "идиотскими" я эти примеры назвать никак не могу. То есть они показывают технологию полиморфизма как факта и не более.
Технология полиморфизма - это дублирование кода.
Весь полиморфный интерфейс дублируется подчастую, во всех потомках.

Даже более того, если нет необходимости интерпретировать абсолютно разные сущности, как одну, но хочется сделать им одинаковый интерфейс для удобства - это тоже уже дублирование кода. Ну и что в этом плохого?
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
26.11.2011, 01:57     Сложность абстракции, полиморфизм, дублирование и другие #10
Цитата Сообщение от Bers Посмотреть сообщение
Ну например, <...> аррэй не входят в поставку 2008 студии.
И это не повод в задаче такого уровня создавать собственный класс. Иными словами, это не повод не использовать std::vector.
Цитата Сообщение от Bers Посмотреть сообщение
Технология полиморфизма - это дублирование кода.
Весь полиморфный интерфейс дублируется подчастую, во всех потомках.
Само слово полиморфизм означает множество различных форм. Как может дублироваться то, что по определению разное? Переписывать надо не все методы, а только те, которые ведут себя по разному. И да, попробуйте-ка, написать все это дело без полиморфизма и тупо сравните количество кода.
Bers
Заблокирован
26.11.2011, 02:38  [ТС]     Сложность абстракции, полиморфизм, дублирование и другие #11
Цитата Сообщение от fasked Посмотреть сообщение
Переписывать надо не все методы, а только те, которые ведут себя по разному.
Я вроде по русски пишу:

Цитата Сообщение от Bers Посмотреть сообщение
Весь полиморфный интерфейс дублируется подчастую, во всех потомках.
Цитата Сообщение от fasked Посмотреть сообщение
И да, попробуйте-ка, написать все это дело без полиморфизма и тупо сравните количество кода.
А я не пытаюсь избежать самого по себе дублирования кода. Меня не парит, если у меня будит десяток классов, каждый из которых будут иметь одноименные интерфейсы в своих заголовках.
Меня даже не парит, если они будут иметь одноименные методы + одноименные реализации этих методов, если это позволит избежать усложнения архитектуры.

И меня не парит, если некоторые из классов будут содержать одинаковые данные члены.

Главное требование - красивая и логичная архитектура. Решение задач в рамках заявленных требований.

Добавлено через 1 минуту
Цитата Сообщение от fasked Посмотреть сообщение
И это не повод в задаче такого уровня создавать собственный класс.
какого такого уровня?
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
26.11.2011, 23:39     Сложность абстракции, полиморфизм, дублирование и другие #12
Bers,
Весь полиморфный интерфейс дублируется подчастую, во всех потомках.
Адовый бред. Используется ОДИН интерфейс, а переопределяется только то, что нужно переопределить.

Во всех потомках (или почти во всех) должен быть РАЗНЫЙ код.
Bers
Заблокирован
26.11.2011, 23:49  [ТС]     Сложность абстракции, полиморфизм, дублирование и другие #13
Цитата Сообщение от ForEveR Посмотреть сообщение
Адовый бред. Используется ОДИН интерфейс, а переопределяется только то, что нужно переопределить.
Во всех потомках (или почти во всех) должен быть РАЗНЫЙ код.
То есть, сам по себе интерфейс за код не щитается, да?
Только реализация интерфейса?

А заголовки, наверное, компилятор сам за программиста пишет?
Он мысли программиста читает, и сам весь полиморфный интерфейс в потомков втыкает?
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
27.11.2011, 00:07     Сложность абстракции, полиморфизм, дублирование и другие #14
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Bers, Пример приведи. Я тебя не понимаю.

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
class Base
{
public:
   virtual void Foo()
   {
       std::cout << "Base" << std::endl;
   }
   virtual ~Base()
   {
   }
};
 
class Der1 : public Base
{
public:
   virtual void Foo()
   {
       std::cout << "Der1" << std::endl;
   }
   virtual ~Der1()
   {
   }
};
 
class Der2 : public Base
{
public:
   virtual ~Der2()
   {
   }
};
Bers
Заблокирован
27.11.2011, 00:30  [ТС]     Сложность абстракции, полиморфизм, дублирование и другие #15
ForEveR, ну я на самом деле уже догадываюсь, почему непонятка вышла.

1.
Класс имеет: прототипы методов, и реализацию этих прототипов (не всегда, и не для всех методов)

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

Ну так вот, список всех прототипов - это интерфейс класса.
а реализация этих прототипов - это реализация интерфейса класса.


То есть, под словом "интерфейс" лично я подразумеваю именно набор прототипов, а не набор прототипов + их реализации.

А вы походу, думаете, что интерфейс это и прототипы, и реализация.

2.
Код на с++ - это все символы из которых конструируется код в терминах с++, включая комментарии.

Заголовок класса - такой же полноценный код на с++, как и реализация этого класса.
И дублирование интерфейса (прототипов) полиморфного потомка является дублированием кода написанного на с++.

Существует множество способов, как можно избежать этого дублирования.
Самый простой и убогий - это например препроцессор (прототипы в отдельном хедере, и инклюдяццо везде, где они нужны)

Одно из моих достижений в этой области - использование кодо-генераторов на макросах с автоматической "чисткой".

То есть, класс создаётся по некоторому шаблону, при помощи макроса.
Но такая запись крайне не читабельная, и ущербна в плане сопровождения.

Однако после первой же удачной компиляции срабатывает "чистка", и вместо "непонятного макроса" в файле оказывается полноценный класс, со всеми своими данными-членами и прочим.
Это тоже дублирование кода, но оно происходит автоматически, и не отбирает у программиста много времени.

При помощи макросов можно автоматизировать развертку целых архитектур. Очень быстро создавать заготовки-паттерны, и тп.

Например, с помощью кодо-генераторов на макросах удалось реализовать идиому "манипулятивных классов" - как одну из возможных замечательных альтернатив полиморфизму.

Смысл которой: если нужно обрабатывать одни и те же данные, но только разными способами, не обязательно городить огород из полиморфов, а можно просто сделать несколько различных обработчиков, умеющих "подключатся" к данным и делать над ними действия.

В данный момент, мне что бы создать очередную заготовку под манипулятор, нужно написать только три строчки макроса.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
27.11.2011, 00:43     Сложность абстракции, полиморфизм, дублирование и другие #16
Bers, блин, ну обсуждали же уже пару месяцев назад всё это. Вы бред говорите, это уже на уровне фанатизма. То, о чём вы говорите, не подпадает под дублирование кода.
Bers
Заблокирован
27.11.2011, 00:50  [ТС]     Сложность абстракции, полиморфизм, дублирование и другие #17
Цитата Сообщение от silent_1991 Посмотреть сообщение
Bers, блин, ну обсуждали же уже пару месяцев назад всё это. Вы бред говорите, это уже на уровне фанатизма. То, о чём вы говорите, не подпадает под дублирование кода.
Я говорю, что дублирование кода на языке с++ никого особо не парит.
Но не нужно путать понятие "дублирование кода" с понятием "дублирование функционала"

А вы мне говорите, что дублирование кода на с++ к дублированию кода не относится.

То есть, копипаста интерфейсов - это типа не дублирование кода? Ну-ну
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
27.11.2011, 01:11     Сложность абстракции, полиморфизм, дублирование и другие #18
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
27.11.2011, 01:38     Сложность абстракции, полиморфизм, дублирование и другие #19
Bers, в каком-то смысле вы правы. Вы только объясните, желательно на конкретных примерах, что вы предлагаете взамен полиморфизму. По-моему, всё равно должно получиться всё то же самое, только сложнее (т.к. средства, заложенные в язык, проще по определению).
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.11.2011, 13:04     Сложность абстракции, полиморфизм, дублирование и другие
Еще ссылки по теме:

C++ Небольшая сложность
Полиморфизм C++
C++ Полиморфизм в с++

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

Или воспользуйтесь поиском по форуму:
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
27.11.2011, 13:04     Сложность абстракции, полиморфизм, дублирование и другие #20
Цитата Сообщение от Bers Посмотреть сообщение
какого такого уровня?
Я имел в виду ту тему, из которой этот разговор вышел.
Цитата Сообщение от Bers Посмотреть сообщение
Класс не обязан содержать реализацию своего интерфейса, и тогда его называют "чисто-абстрактным классом".
Правда? Я то всегда думал, что абстрактный класс - тот, который имеет хотя бы один чисто виртуальный метод.

Цитата Сообщение от Bers Посмотреть сообщение
То есть, класс создаётся по некоторому шаблону, при помощи макроса.
Еще бы она была не ущербна. Мне ведь не нужно копировать вообще все прототипы функций.
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <memory>
#include <iostream>
 
class Base {
public:
   virtual ~Base() = 0;
 
   virtual void foo() {
      std::cout << "base foo " << std::endl;
   }
   
   virtual void bar() {
      std::cout << "base bar " << std::endl;
   }
   
   virtual void quz() {
      std::cout << "base quz " << std::endl;
   }
};
 
Base::~Base() { }
 
class Derived1 : public Base {
public:
   virtual ~Derived1() { 
   }
   
   virtual void quz() {
      std::cout << "derived 1 quz " << std::endl;
   }
};
 
class Derived2 : public Base {
public:
   virtual ~Derived2() { 
   }
   
   virtual void bar() {
      std::cout << "derived 2 bar " << std::endl;
   }
};
 
void foo(Base *p) {
   p->quz();
   p->foo();
   p->bar();
}
 
int main() {
   Base *p1 = new Derived1();
   Base *p2 = new Derived2();
      
   foo(p1);
   foo(p2);
   
   delete p1;
   delete p2;
   
   return 0;
}
Ну и можно сказать, что методов в базовом классе может быть вообще-то больше чем два или три. И они могут быть гораздо сложнее.
Yandex
Объявления
27.11.2011, 13:04     Сложность абстракции, полиморфизм, дублирование и другие
Закрытая тема Создать тему
Опции темы

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