Как сделать массив классов в c

Добавил пользователь Валентин П.
Обновлено: 10.09.2024

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

и тогда я могу использовать это для каждого индекса:

Но можно ли объявить массив, а затем использовать что-то вроде этого?

С уважением, Синотикс

Решение

Да, ты можешь сделать это Но для этой цели вы должны использовать наследование и полиморфизм в C ++.

Что вы можете сделать, это.
Создайте родительский класс, т.е.

Затем наследуйте все ваши классы, как в вашем случае, которые являются Class1, Class2, Class3
от родитель учебный класс. Также создайте виртуальный метод в родительском классе, чтобы получить полиморфизм в C ++.

Таким образом, вы сможете сделать это.

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

Другие решения

Это может быть возможно, если вы используете основной класс в качестве родительского и классов Class1, Class2 and Class3 должны быть подклассами основного класса.

Если все ваши классы (1-3) extend из класса, например ParentClass Вы могли бы написать:

Это возможно, но что вы хотите сделать с массивом? Если все ваши классы имеют общий базовый класс, вы можете определить свой массив, содержащий указатели на этот базовый класс, а затем добавить классы в массив, как вы это сделали.

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

Несколько предложений: я хотел бы предложить, чтобы ваш базовый класс имел virtual деструктор, это означает, что когда вы delete элементы массива он будет вызывать деструктором в производном классе. Кроме того, я предлагаю использовать умные указатели вместо сырых указателей, чтобы вам не нужно было звонить delete , Вот пример, я использовал vector вместо массива и шаблона класса для определения классов:

При решении задач с большим количеством данных одинакового типа использование переменных с различными именами, не упорядоченных по адресам памяти, затрудняет программирование. В подобных случаях в языке Си используют объекты, называемые массивами.

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

Массив характеризуется следующими основными понятиями:

Элемент массива (значение элемента массива) – значение, хранящееся в определенной ячейке памяти, расположенной в пределах массива, а также адрес этой ячейки памяти.
Каждый элемент массива характеризуется тремя величинами:

  • адресом элемента — адресом начальной ячейки памяти, в которой расположен этот элемент;
  • индексом элемента (порядковым номером элемента в массиве);
  • значением элемента.


Адрес массива – адрес начального элемента массива.

Имя массива – идентификатор, используемый для обращения к элементам массива.

Размер массива – количество элементов массива

Размер элемента – количество байт, занимаемых одним элементом массива.

Расположение массива в памяти

Графически расположение массива в памяти компьютера можно представить в виде непрерывной ленты адресов.

Представленный на рисунке массив содержит q элементов с индексами от 0 до q-1 . Каждый элемент занимает в памяти компьютера k байт, причем расположение элементов в памяти последовательное.

Адреса i -го элемента массива имеет значение

n+k·i

Адрес массива представляет собой адрес начального (нулевого) элемента массива. Для обращения к элементам массива используется порядковый номер (индекс) элемента, начальное значение которого равно 0 . Так, если массив содержит q элементов, то индексы элементов массива меняются в пределах от 0 до q-1 .

Длина массива – количество байт, отводимое в памяти для хранения всех элементов массива.

ДлинаМассива = РазмерЭлемента * КоличествоЭлементов

Для определения размера элемента массива может использоваться функция

Объявление и инициализация массивов

Для объявления массива в языке Си используется следующий синтаксис:

тип имя[размерность]=;

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

Если количество инициализирующих значений, указанных в фигурных скобках, меньше, чем количество элементов массива, указанное в квадратных скобках, то все оставшиеся элементы в массиве (для которых не хватило инициализирующих значений) будут равны нулю. Это свойство удобно использовать для задания нулевых значений всем элементам массива.

Если массив проинициализирован при объявлении, то константные начальные значения его элементов указываются через запятую в фигурных скобках. В этом случае количество элементов в квадратных скобках может быть опущено.

При обращении к элементам массива индекс требуемого элемента указывается в квадратных скобках [] .

Однако часто требуется задавать значения элементов массива в процессе выполнения программы. При этом используется объявление массива без инициализации. В таком случае указание количества элементов в квадратных скобках обязательно.

Для задания начальных значений элементов массива очень часто используется параметрический цикл:

Массив

Результат выполнения программы

Многомерные массивы

В языке Си могут быть также объявлены многомерные массивы. Отличие многомерного массива от одномерного состоит в том, что в одномерном массиве положение элемента определяется одним индексом, а в многомерном — несколькими. Примером многомерного массива является матрица.

Общая форма объявления многомерного массива

Элементы многомерного массива располагаются в последовательных ячейках оперативной памяти по возрастанию адресов. В памяти компьютера элементы многомерного массива располагаются подряд, например массив, имеющий 2 строки и 3 столбца,

Двумерный массив

Общее количество элементов в приведенном двумерном массиве определится как

КоличествоСтрок * КоличествоСтолбцов = 2 * 3 = 6.

Количество байт памяти, требуемых для размещения массива, определится как

КоличествоЭлементов * РазмерЭлемента = 6 * 4 = 24 байта.

Инициализация многомерных массивов

Значения элементов многомерного массива, как и в одномерном случае, могут быть заданы константными значениями при объявлении, заключенными в фигурные скобки <> . Однако в этом случае указание количества элементов в строках и столбцах должно быть обязательно указано в квадратных скобках [] .

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

Результат выполнения

Результат выполнения

Передача массива в функцию

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


Исключение составляют функции обработки строк, в которые достаточно передать только адрес.

При передаче переменные в качестве аргументов функции данные передаются как копии. Это означает, что если внутри функции произойдет изменение значения параметра, то это никак не повлияет на его значение внутри вызывающей функции.

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

Пример на Си Дан массив из 10 элементов. Поменять местами наибольший и начальный элементы массива. Для операций поиска максимального элемента и обмена использовать функцию.

Поменять местами наибольший и первый элементы массива

Результат выполнения


Пример на Си Дан массив размерности n. Вычислить произведение четных элементов

Произведение четных элементов массива

Результат выполнения

Здравствуйте !Подскажите пожалуйста, как в заполненном одномерном массиве найти номера элементов, которые больше 10, и количество таких элементов? А обнаруженные номера вывести в порядке их роста.

В цикле сравнить каждый элемент массива с 10. Если больше, вывести номер и увеличить количество на 1.

Добрый день) Хоть убейте но не могу сделать задачу: создать 3х7 массив чтобы считало температуру в трех городах (Моска, Питер, Ростов) всю неделю с соотвевтсвующим выводом информации (Самую высокую и низкую темпиратуру среди всех трех городов за все дни недели, самую низкую темпиратуру в Москве, город с самой большой температурой в среду, самую низкую и высокую среднею температуру и в каком городе) Дошел до вот этого момента, а дальше вывод информации, привязка дней недели итд я не помню((

int i, j, min, imin, jmin, max, imax, jmax;
int a [3][7];

for (i=0; i for (j=0; j "Give temperature [%d][%d]= " ,i+1, j+1);
scanf( "%d" , &a[i][j]);
>

max = a[0][0];
imax = 0;
jmax = 0;
for (i=0; i for (j=0; j if (a[i][j] > max)
max = a[i][j];
imax = i;
jmax = j;
>

min = a[0][0];
imin = 0;
jmin = 0;
for (i=0; i for (j=0; j if (a[i][j] for (i=0; i for (j=0; j "%d \t" ,a[i][j]);
printf( "\n" );
>
printf( "\n" );

printf( "Maximum temperature %d and its in %d and in column %d \n " , max, imax+1, jmax+1);
printf(Minimum temperature %d and its in %d and in column %d \n ", min, imin+1, jmin+1);

Пока не пойму, в чем сложность? Температуру в Москве найти? Или в среду? Индексы соответствуют дням недели. Неделя в какой день начинается? И какой по счету день "среда"? Сравниваем a[0][среда], a[1][среда] и a[2][среда]

Чтобы изменять размер массива, можно воспользоваться динамическим выделением памяти.
Чтобы случайные числа не повторялись - возможно два варианта
1. Перетасовать случайным образом последовательность чисел. 2. При генерации следующего случайного числа сравнивать его со всеми предыдущими.

Вопрос по поводу работы с массивом из функции: Что произойдёт с данными исходного массива, если я: - передам указатель на массив и его размер в функцию - внутри функции создам копию исходного массива и изменю её - изменю указатель так, чтобы он ссылался на изменённую копию исходного массива Эти данные просто станут "мусорными" значениями или удаляться (как в Python)?

Так лучше не делать! Выделенная память не будет корректно освобождена до завершения работы программы.

Добрый день. Вопрос по поводу указания размера массива. Я считал, что память под статический массив выделяется при компиляции и размер массива должен быть указан константой (как минимум в соответствии с требованиями стандарта ANSI C). Однако к моему удивлению при объявлении массива размера n (неизвестного на этапе компиляции) компилятор (mingw64 под Win) не выдает ни ошибок, ни предупреждений причем при разных стандартах (-std=c89,c90,c99. ) и включении отображения ошибок (-Wall):

int i, a[n]; // Почему не ругается?

Здравствуйте! Компилятор gcc 5.1.0 c11. int a = 10; int arr[a]; Ошибки нет. Стивен Прата в книге "Язык программирования С лекции и упражнения" 6 издание пишет: "int n = 5; float a8[n]; // не было разрешено до появления стандарта С99".

Здравствуйте, Елена! Спасибо Вам за статью! У меня есть один вопрос по массивам переменной длины. В одной книге прочел "Понятие переменный в массиве переменной длины вовсе не означает возможность изменения длины массива после его создания. Будучи созданным, массив переменной длины сохраняет тот же самый размер. В действительности понятие переменный означает, что при указании размерностей при первоначальном создании массива можно использовать переменные" Я выполнил упражнение из книги в DevC++, у меня программа запрашивает ввод количества строк и столбцов двумерного массива. Потом производит операции с массивом: вычисляет среднее значение, наибольшее значение в каждом одномерном массиве, наибольшее значение среди всех одномерных массивов и выводит данные на экран. Все это происходит в бесконечном цикле while (1) пока пользователь на запрос не введет значение отличное от 1 - тогда сработает оператор break. У меня в цикле while() каждый раз размер массива вводится с помощью scanf ("%lf", &str ), scanf ("%lf", &stlb ) без всякой динамической памяти и нормально программа работает т.е. пользователь может менять размер массива много раз и код компилируется. Вопрос - почему размер массива меняется и ошибки не выдается? Мне вот это непонятно. Заранее благодарен.

int vvod_massiva ( const double [][stlb]);
double srednee_znach ( const double [][stlb], int n);
double srednee_znach_vseh ( const double [][stlb]);
double bolshee_znach ( const double [][stlb]);
int vuvod_znach ( const double [][stlb], double [], double , double );
int main( void )


const double massiv[str][stlb];
double sred [stlb];
double c;
double d;
int i=0;
int j=0;
int ch;

while (1)
printf ( "Введите количество строк\n" );
scanf( "%d" , &str);
printf ( "Введите количество столбцов\n" , stlb);
scanf( "%d" , &stlb);
printf ( "Введите %d массива по %d элементов типа double каждый\n" , str, stlb );

for (i=0, j=0; i "Для повтора программы нажмите -1. Для завершения - 2\n" );
scanf( "%d" , &ch);
if (ch!=1)
break ;
>

int vvod_massiva ( const double a[][stlb])

int stroka;
int stolbets;

for (stroka=0; stroka for (stolbets=0; stolbets "%lf" , &a[stroka][stolbets]);

double srednee_znach ( const double a[][stlb], int n)
double sum=0;
double srednee=0;
int i;

for (i=0; i return srednee;

double srednee_znach_vseh ( const double a[][stlb])
int stroka;
int stolbets;
double sum=0;
double srednee;
for (stroka=0; stroka for (stolbets=0; stolbets "%f\n" , sum );
return srednee;
>


double bolshee_znach ( const double a[][stlb])
<
int i=0;
int j;
int n=1;
int p1=1;
double massiv [str];
int k;
for (j=0, k=0; j while (p1 if (a[j][i] else

>
int vuvod_znach ( const double a[][stlb], double b[], double c, double d)

int stroka;
int stolbets;
int i;
int j;

for (stroka=0; stroka for (stolbets=0; stolbets "%f " , a[stroka][stolbets]);

>
for (i=0; i "Среднее значение %d - массива равно %f\n" , i+1, b[i] );

printf( "Среднее значение из %d равно %f\n" , (str*stlb), c );
printf( "большее значение из %d равно %f\n" , (str*stlb), d );

Мне тоже непонятно, что это за компилятор такой. Visual Studio 2019 на этот код 14 ошибок показывает.

Вместо введения

Допустим, у вам необходимо хранить в вашей программе 10 целочисленных значений. С одной стороны, если вам не лень (и не жалко тех, кто будет смотреть Ваш код) вы можете объявить 10 переменных типа int , инициализировать их и работать. А что делать, если требуется 100 значений или 1000? Опять же, можно сходить с ума и заводить под каждое значение отдельную переменную, а можно сделать проще — объявить переменную-массив и хранить в ней все значения.

где Type — это тип элементов массива, а ArrayName — его имя. То есть, визуально, массив от обычной переменной отличает наличие после названия типа данных квадратных скобок. Например, вот так можно определить массив целых чисел типа int :

Так можно объявить массивы строк и вещественных чисел:

Например, создадим массив, который будет хранить 5 чисел типа int :

В цикле foreach

Выше я показал один из способов как перебрать элементы массива с использованием цикла foreach :

Здесь в цикле foreach мы указали тип элементов int , так как у нас массив содержит элементы этого типа и после ключевого слова in указали массив элементы которого необходимо перебрать. Если бы у нас был массив строк, то цикл выглядел бы, соответственно, следующим образом:

Цикл foreach достаточно удобный для работы, но иногда бывает так, что возможностей цикла не достаточно. Например, мы создаем массив и нам требуется обеспечить доступ только к элементам с чётными индексами (0, 2, 4, 6 и т.д.). Технически, мы можем использовать тот же foreach , ввести дополнительную переменную и с помощью неё проверять какой индекс у очередного элемента, но это усложнит наш код. Более гибким в этом плане является цикл for в котором мы можем задавать порядок выполнения.

В цикле for

С этим циклом мы тоже уже знакомы. Попробуем реализовать озвученный выше вариант перебора элементов массива — прочитать значения только элементов с чётными индексами. С циклом for это можно сделать, например, вот так:

Вывод консоли будет выглядеть следующим образом:

Счётчик цикла: 1. Читаем элемент с индексом 2 значение: 16

Счётчик цикла: 2. Читаем элемент с индексом 4 значение: -12

Счётчик цикла: 3. Читаем элемент с индексом 6 значение: 80

Счётчик цикла: 4. Читаем элемент с индексом 8 значение: 90

Счётчик цикла: 5. Читаем элемент с индексом 10 значение: 102

Условие в теле цикла:

Требуется для того, чтобы мы не вышли за границы массива. Так, уже на шестом шаге цикла мы бы получили то, что должны прочитать элемент с индексом 6*2=12 которого не существует (максимальный индекс у нас в примере — 10 ) и программа бы выдала нам исключение:

Выход за границы массива. Поэтому мы и обезопасили себя от этого исключения сделав проверку — элемент массива с каким индексом мы пытаемся проверить, а сам цикл закончился аккурат на пятом шаге.

Многомерные массивы

До сих пор мы имели дело с так называемыми одномерными массивами, которые можно себе представить в уме как ряд переменных (числовых, строковых, символьных и т.д.). Визуально, наши одномерные массивы выглядели так:

Инициализируются многомерные массивы точно также, как и одномерные — необходимо задать количество элементов в каждом измерении. Например, зададим массив состоящий из двух столбцов и пяти строк:

Теперь, чтобы обратиться как какому-либо элементу массива, нам необходимо указывать два индекса — индекс строки и индекс столбца. Например, получим значение из четвертой строки второго столбца. Так как нумерация элементов в массивах начинается с нуля, то код будет такой:

Название Тип данных Описание
Length int Возвращает общее число элементов во всех измерениях массива
Rank int Получает ранг (число измерений) массива
Long Length long Возвращает 64-разрядное целое число, представляющее общее число элементов во всех измерениях массива
Название Тип данных Описание
Get Length() int Возвращает 32-разрядное целое число, представляющее количество элементов в заданном измерении массива
Get Lower Bound() int Получает Индекс первого элемента заданного измерения в массиве
Get Upper Bound() int Получает Индекс последнего элемента заданного измерения в массиве.

В цикле foreach

Цикл foreach предоставляет нам самый простой и понятный способ доступа к каждому элементы массива. Например, возьмем наш двумерный массив и попробуем перебрать все его элементы в цикле foreach:

В результате, в консоли появится строка, содержащая элементы массива:

В цикле for

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

Второй вариант — нам надо прочитать значения в последнем столбце массива, но, при этом мы не знаем размерность второго измерения. Чтобы было по-понятнее, я объявил в коде две дополнительные переменные :

В цикле мы запрашиваем элемент с индексами:

Соответственно, если необходимо пройти по всем элементам массива, то можно использовать вложенные циклы for и организовать доступ к элементам массива в любом порядке — построчно, по столбцам…да хоть по диагонали — тут всё будет зависеть от задачи.

Массив массивов — это массив, элементы которого сами являются массивами. Элементы массива массивов могут иметь различные измерения и размеры. Массив массивов также иногда называется нерегулярным или зубчатым массивом. Объявление массива массивов выглядит следующим образом:

Теперь наш массив содержит три массива на 2, 3 и 4 элемента соответственно и каждый из этих массивов будет содержать целые числа. Чтобы заполнить массив значениями элементов, можно воспользоваться любым из способов, которые мы рассмотрели для одномерных массивов, например, так:

Для доступа к элементам массива массивов необходимо использовать вот такую языковую конструкцию:

Неявно типизированные массивы

При этом, если Вы попытаетесь объявить вот такой массив:

Работать с такими массивами можно точно также, как и со всеми другими типами массивов, которые были рассмотрены выше.

Итого

Есть класс Rectangle (прямоугольник). У него есть размеры по x и y и координаты центра.

Наследованием созданы классы ColoredRectangle (цветной прямоугольник) и PatternedRectangle (прямоугольник с текстурой). У обоих есть функции Draw(), рисующие их.

Надо сделать массив (желательно, vector) rectangleMass, содержащий как цветные, так и текстурированные прямоугольники, чтобы потом пройтись по нему, вызывая для каждого элемента Draw. Также нужен массив (опять же, желательно vector), содержащий указатели на некоторые элементы из rectangleMass.

Ман виртуальные методы.
class Rectange public:
virtual void Draw() = 0;
>
std::vector


то ли дело на питоне

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

создаётся абстрактный класс Rectangle, от него наследуются ColoredRectangle и PatternedRectangle. Создаём vector rectangleVector и можем с ним работать как хочется, верно? Или как? Как будет использоваться этот вектор?

А если у ColoredRectangle есть функция SetColor() (которая отсутствует у PatternedRectangle), я могу сказать rectangleVector.SetColor(. ), если i-й элемент заведомо является ColoredRectangle'ом?

или я всё неправильно понял?

бери книги и учи основы

Самый дебильный вариант:
[code=cpp]
class Rectangle
public:
virtual void Draw() = 0;
virtual void SetColor()<>
>;

class ColoredRectangle: public Rectangle
public:
virtual void Draw() .
>
virtual void SetColor() .
>
>

class PatternedRectangle : public Rectangle
public:
virtual void Draw() .
>
>;

std::vector vect;
vect.push_back(new ColoredRectangle());
vect.push_back(new PatternedRectangle());

[/code]Не очень красиво, зато безопасно :)

быдлокод во всей красе

А что ты хотел?
Я и написал, дебильный вариант.

> Я и написал, дебильный вариант.

Напиши доходчиво, правильно, что бы было просто для понимания?

> Напиши доходчиво, правильно, что бы было просто для понимания?

если человек не знает про виртульные методы, абстрактные методы и классы, dynamic_cast и QI и т.д. и т.п., то смысл ему показывать на пальцах решение и разжевывать что к чему? это ведь не что-то сверхъестестенное - открыть хотя бы того же Страуструпа и прочитать

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

я уже всё понял, просто сначала под пивом кусок Шилдта не осилил

это я тоже знаю, хочу обойтись без cast

можешь показаться не дебильный вариант (без разжёвывания), я с утра разберусь?

> можешь показаться не дебильный вариант (без разжёвывания), я с утра разберусь?

то есть показать.

ещё можно отослать на нужную часть литературу

в идеале — показаться пример и отослать на литературу

> нужную часть литературу

всё, надо спать, башка и так 6й час как не варит

> можешь показаться не дебильный вариант

создаешь интерфейс I_Rectangle, потом его базовую реализацию - Rectangle, потом дочерние классы ColoredRectangle и PatternedRectangle , и набиваешь в вектор std::vector создаваемые объекты

если i-й элемент заведомо является ColoredRectangle'ом


делаешь dynamic_cast, проверяешь на NULL и вызываешь метод, хотя опять же - по хорошему код, знающий, что данный объект именно ColoredRectangle, должен быть в самом ColoredRectangle, либо дочерних классах от него ( как простой вариант - это вызов диалога смены цвета, например, и тогда нужен еще один интерфейс, чтоб получить контекстное меню или тот же диалог свойств, ну то уже я увлекся )

Также нужен массив (опять же, желательно vector), содержащий указатели на некоторые элементы из rectangleMass.


указатели на элементы вектора делать нельзя( т.е. можно - но будешь ССЗБ )

> ещё можно отослать на нужную часть литературу

на нужную не укажу - так как читать выборочно нет смысла, а из популярных( даже попсовых ) - Мартин Фаулер, Александреску, Страуструп, Джоэль, Мейерс, Макконнелл и т.д.

> указатели на элементы вектора делать нельзя( т.е. можно - но будешь ССЗБ )

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

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

> а во-вторых это ты сейчас не собираешься менять исходный вектор, а потом понадобится - и ты без тени смущения это сделаешь, т.к. забудешь про эту завязку, и веселые, почти рандомные глюки, будут обеспечены

тут просто матмодель такая, что не придётся менять исходный вектор.

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

1. создать массив прямоугольников

2. для каждого прямоугольника заполнить массив соседей указателями на соответствующих соседей

> для каждого прямоугольника заполнить массив соседей указателями на соответствующих соседей

а зачем тут делать указатель на элемент вектора? копируешь указатель на сам объект и все

в общем, для реализации того, что мне нужно, следует заботать абстрактные классы и интерфейсы, так?

ещё небольшое пояснение. у меня есть два типа прямоугольников. прямоугольники первого типа влияют на соседей, но сами никогда не меняются. прямоугольники второго типа влияют на соседей, а соседи влияют на них. Для прямоугольников второго типа есть понятие внутренней энергии, она-то и меняется; для первого типа прямоугольников этого понятия нет. Поэтому я и спрашивал про SetColor(), существующий только для одного типа.

тут хватит интерфейсов и классов, или таки нужно использовать dynamic_cast?

можешь показать разницу между указателем на элемент вектора и на сам объект?

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

> тут хватит интерфейсов и классов, или таки нужно использовать dynamic_cast?

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

А что здесь быдлокодерского?

то что в один класс намешали все, что захотели - и абстрактные методы, и метод SetColor, который собственно к Rectangle никаким боком не относится - т.е. костыль, и судя по условию тут еще и собсвенно реализация базового класса - выставление позиции и размеров, вобщем каша, а не код

Такой вариант тоже является быдлокодом и костылем для замены dynamic_cast'а?

Используйте разные массивы для разных интерфесов. А эти массивы положите в другой массив.

> Такой вариант тоже является быдлокодом и костылем для замены dynamic_cast'а?

Что такое QI? Гугл, кроме языка программирования Qi, ничего не подсказывает?

// совершенно другой анонимус

Т.е. в Qt быдлокод? QDomNode умеет:

// все тот-же, совершенно другой, анонимус

>Что такое QI? Гугл, кроме языка программирования Qi, ничего не подсказывает?
То же самый набор массивов, про который я писал, но только с методом возвращающим нужный массив/сущность.

Я полагаю, что он имел ввиду то, что такой код неуместен в данном случае.


Тем не менее, мне тоже интересно знать, что же такое QI? Похоже, что-то очень популярное, раз lester не удосужился заранее предоставить линк или какое-нибудь минимальное объяснение.

// тот самый первый анонимус

> Что такое QI?

> Т.е. в Qt быдлокод? QDomNode умеет:

// Dynamic cast
virtual bool isAttr() const < return false; >
virtual bool isCDATASection() const < return false; >
virtual bool isDocumentFragment() const < return false; >
virtual bool isDocument() const < return false; >
virtual bool isDocumentType() const < return false; >
virtual bool isElement() const < return false; >
virtual bool isEntityReference() const < return false; >
virtual bool isText() const < return false; >
virtual bool isEntity() const < return false; >
virtual bool isNotation() const < return false; >
virtual bool isProcessingInstruction() const < return false; >
virtual bool isCharacterData() const < return false; >
virtual bool isComment() const

это нормальный код?

т.е. лучше каждый раз делать dynamic_cast и сравнивать с нулем, чтобы узнать, это искомый тип или нет?

> т.е. лучше каждый раз делать dynamic_cast и сравнивать с нулем, чтобы узнать, это искомый тип или нет?

нет конечно - лучше брать тип и сравнивать

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


И все блин дружно забыли про виртуальные деструкторы. Мемори ликов захотелось?

> И все блин дружно забыли про виртуальные деструкторы. Мемори ликов захотелось?

тоже верно - не обратил внимания на этот недочет

Ещё заслуживает внимания идея группировки интерфейсов. Грубо говоря есть массив массивов объектов и при запросе конкретного интерфейса, возвращается указатель на первый массив + диапазон(кол-во массивов). Таким образом мы получаем все объекты данного интерфейса, несмотря на то что могут попадаться и производные запрошенному интерфейсу классы.


А есть способ сделать, чтобы это работало быстрее?

>это нормальный код?

А есть способ сделать, чтобы это работало быстрее?



ИМХО былокод имеет место быть.

1. SetColor() в базовом классе как я понял не нужен.

2. virtual void SetColor()<>. Объявление отдельно, реализация отдельно.

Предлагаю свой вариант (для обсирания)


>2. virtual void SetColor()<>. Объявление отдельно, реализация отдельно.

Бред читой воды.

Но в целом согласен, я бы тоже не стал городить лишнийх интерфейсов по чем зря.

А есть способ сделать, чтобы это работало быстрее?

конечно, у них это потом еще раз обернуто:

и обычный node.mType == kCDATASection будет однозначно в разы быстрее вызова виртуального метода node->isCDATASection()

Читайте также: