Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Хочу сделать класс массива  (Прочитано 12476 раз)
0 Пользователей и 1 Гость смотрят эту тему.
jur
Помогающий

lt
Offline Offline

« : 18-09-2013 16:24 » 

Заранее прошу прощения! Простенький попутный вопрос (совсем не в тему, но не хочется создавать новую). Хочу сделать класс массива, который в использовании выглядел бы точно так же, как обычный массив элементов (например, чисел типа int). Как-то так:

Код:
class SMayArray
{
....
};

SMayArray MyArray(10);     // Конструктор принимает число - размер массива

int variable = MyArray[3]; // Берем 3-й элемент массива (1)

MyArray[5] = 1234;         // Приравниваем значение 5-му элементу массива (2)

Я в этих хитрых классовых примочках не очень... :-) Взятие элемента массива (1) проблемы не составляет, делаю operator[] и все. А вот как сделать (2) - никак не допру... Тут ведь сразу два оператора: взятие индекса и приравнивание. Делать что-то вроде метода Add не хочу - нарушится красивая простота. А я очень люблю красивую простоту :-)

Это же, наверное, совершенно элементарно, но до меня никак не доходит...

Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 18-09-2013 16:45 » 

jur, гораздо бОльшая загадка - чем тебя стандартный vector не устраивает, который это всё делает в C++.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
jur
Помогающий

lt
Offline Offline

« Ответ #2 : 18-09-2013 17:03 » 


Я свой хочу :-) Ведь если я буду применять "кубики", а-ля Бэйсик, я останусь на уровне начинающих программеров, которые из кубиков что-то сваять могут, но "шаг влево, шаг вправо - ...".  А создав с вашей помощью свой такой класс, я смогу понять "классовое" программирование чуть лучше.

Записан

MPEG-4 - в массы!
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 18-09-2013 17:25 » 

Т.е. если ты научишься водить экскаватор вместо того, чтобы использовать лопату, то будешь деградировать? Ущербная логика.
Да, в учебных целях это полезно, но практического смысла писать свое нет.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
jur
Помогающий

lt
Offline Offline

« Ответ #4 : 18-09-2013 18:09 » 

Т.е. если ты научишься водить экскаватор вместо того, чтобы использовать лопату, то будешь деградировать? Ущербная логика.
Да, в учебных целях это полезно, но практического смысла писать свое нет.

Разве я хоть пол-слова сказал о деградации?! А насчет экскаватора... Ну вот попросила жена под окнами выкопать ямку, посадить цветы. А ты в недоумении чешешь репу, не представляя, как сюда, под окно, втиснуть этот проклятый экскаватор! :-)

Поэтому насчет практики - в корне не согласен. Опять же, а моя родная область embedded, где половины этих примочек вообще нет, а остальные работают незнамо как? А ограниченность в ресурсах, а быстродействие? Поэтому я и говорю, что обычный клепатель из кубиков быстро сбацает приложение, которое заработает на мощном, современном компе. И на всякие тонкости ему плевать. А я разрабатываю приборы :-) Тут мощный, геймеровский комп с восьмой Виндой не применишь.

К вопросу. Оказалось, что все очень просто. Набросал такой примерчик:

Код:
class SArray
{
public:
  SArray(int size) : _dummy(0) { _array = new int[size]; _array_size = size; }
  ~SArray() { if(_array) delete [] _array; }

  int operator[](int i) const
  {
    if(_array == 0)                     return 0;
    if( (i < 0) || (i >= _array_size) ) return 0;
    return _array[i];
  }
  int& operator[](int i)
  {
    if(_array == 0)                     return _dummy;
    if( (i < 0) || (i >= _array_size) ) return _dummy;
    return _array[i];
  }

private:
  int  _dummy;
  int* _array;
  int  _array_size;
};

Работает в точности, как простой массив:

  SArray a(3);
  a[0] = 1;
  a[1] = a[0] + 1;
  a[2] = a[1] + 2;

Значения элементов массива: 1, 2 и 4.

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

P.S. Теперь попытаюсь сделать оператор копирования (или как его назвать), чтобы копировать данные примерно так:

int dest[3];

CopyMemory(dest, a, sizeof(a));

« Последнее редактирование: 18-09-2013 18:16 от jur » Записан

MPEG-4 - в массы!
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 18-09-2013 19:03 » new

И в чем смысл? Выход за пределы массива — логическая ошибка. Надо исключение создавать, а не фиктивное значение возвращать.

Код: (C++)
#include <vector>

typedef std::vector<int> vec_int_t;

int main() {
  vec_int_t array(3);

  for (int i = 0; i < 3; i++) {
    array[i] = i + 1;
  }

  array.resize(4); // такого твой массив не умеет ;)
  array.at(3) = 4; // а тут исключение — нет такого элемента

  return 0;
}

http://www.cplusplus.com/reference/vector/vector/
Есть std::array без возможности изменения размера. Тот же вектор, только в профиль. http://www.cplusplus.com/reference/array/array/

В чем еще достоинство STL, что это шаблоны и с их помощью можно создать класс для работы с любым типом.
« Последнее редактирование: 18-09-2013 19:17 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 18-09-2013 22:03 » 

Цитата: jur
а моя родная область embedded, где половины этих примочек вообще нет
Бывает, и "красивых" операторов нет, и классов тоже Ага vector и STL вообще включены в стандарт языка: не знаешь их - не знаешь языка. Вот и вся логика.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #7 : 19-09-2013 09:32 » 

Заранее прошу прощения! Простенький попутный вопрос (совсем не в тему, но не хочется создавать новую).

Совершенно напрасно. Разные темы, более того - разделы, для того и существуют чтобы облегчить жизнь не только спрашивающего, но и отвечающих. Например, эта тема явно относится к отделу "Начинающим". Этим бы ты сразу сэкономил себе и другим "нападки" матёрых профи. Ага

Посему туда её и переносим.

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

Абсолютное заблуждение. Никогда и никому это больше не говори. Посмотрел бы я не начинающих программеров, которые бы начинали с игры в STL-"кубики" 11-го С++.

Цитата
А создав с вашей помощью свой такой класс, я смогу понять "классовое" программирование чуть лучше.

Вот так лучше. Поэтому всю остальную демагогию про экскаваторы опускаем.
jur, ты вобще что хочешь? Сейчас и в будущем? Сделал сиюминутную задачу и забыл, или планируешь серьёзно заниматься ООП (объектно-ориентированным программированием, которое ты называешь "классовым")? Если второе, то расскажи что у тебя уже есть в голове (сколько страничек Страуструпа прочитал?).
« Последнее редактирование: 19-09-2013 09:34 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 19-09-2013 16:20 » 

int dest[3];

CopyMemory(dest, a, sizeof(a));
Если правильно понимаю, что ты хочешь, то оператор приведения типа operator type() посмотри. В твоём случае будет что-то вроде operator int*(). Но с sizeof так уже не проканает.
Только аккуратнее: у такого синтаксического сахара рано или поздно вылезают проблемы с неочевидностью поведения кода. Рано или поздно получится WTF-конструкция, которая ведёт себя не так, как хотелось. Собственно, я думаю, это одна из основных причин, почему вектор из stl так не делает, и приходится изворачиваться, чтобы приладить его к c-коду.
« Последнее редактирование: 19-09-2013 16:27 от Вад » Записан
jur
Помогающий

lt
Offline Offline

« Ответ #9 : 23-09-2013 12:46 » 


Цитата
А создав с вашей помощью свой такой класс, я смогу понять "классовое" программирование чуть лучше.
Вот так лучше. Поэтому всю остальную демагогию про экскаваторы опускаем.

Про экскаватор - это не я первый начал! :-)

jur, ты вобще что хочешь? Сейчас и в будущем? Сделал сиюминутную задачу и забыл, или планируешь серьёзно заниматься ООП (объектно-ориентированным программированием, которое ты называешь "классовым")? Если второе, то расскажи что у тебя уже есть в голове (сколько страничек Страуструпа прочитал?).

Хм... Сложный вопрос! :-) Страуструпа, а также еще парочку книг, я давно прочитал. И периодически перечитываю. Но... Как там в старом анекдоте? "Прочитал Хэмингуэя - не понял ни... (дальше малолитературно)" :-)

Серьёзно заниматься ООП мне, в общем-то, не очень нужно. Но мне крайне важно понимать, как работает написанный мною код. Поэтому я стараюсь минимизировать размер "черного ящика" в моей программе. Т.е. чтобы та часть кода, которую я не вижу, не понимаю и не знаю (что там внутри Винды, или в каких-то внешних модулях), была как можно меньше.

Как-то так...

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

Да, похоже на то. Сделаю метод Size(); и буду просто обращаться непосредственно к самому массиву данных.

Большое спасибо за помощь!

Записан

MPEG-4 - в массы!
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 23-09-2013 18:10 » 

Да, похоже на то. Сделаю метод Size(); и буду просто обращаться непосредственно к самому массиву данных.

Большое спасибо за помощь!
Строго говоря, есть ведь в STL алгоритм поэлементного копирования std::copy - я предпочитаю им пользоваться для коллекций (или для копирования из сырой памяти в вектор, например, хотя MS-вариант не очень такое любит и кормит warning-ами, которые приходится душить).
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines