Russian Qt Forum

Программирование => С/C++ => Тема начата: time.h от Июнь 16, 2011, 14:59



Название: Реализация класса
Отправлено: time.h от Июнь 16, 2011, 14:59
Нужно написать класс, который содержит несколько одинаковых наборов переменных различных типов.
Как это грамотно реализовать?Правильно ли будет написать для этого набора переменных свой класс?


Название: Re: Реализация класса
Отправлено: Amigo_sa от Июнь 16, 2011, 15:02
Если вы планируете хранить лишь набор переменных без методов, то грамотнее сделать структуру.
Код:

struct STicket
{
   QString name;
   int level;
   qreal difficulty;
   bool isDocumented;
}

************

STicket ticket;
ticket.isDocumented = false;


Название: Re: Реализация класса
Отправлено: Пантер от Июнь 16, 2011, 15:04
Amigo_sa: в с++ структура == класс. За исключением private/public.


Название: Re: Реализация класса
Отправлено: Amigo_sa от Июнь 16, 2011, 15:05
Я знаю. Просто в структуре нужно писать на одно слово меньше, потому что по умолчанию методы и данные и так public


Название: Re: Реализация класса
Отправлено: time.h от Июнь 16, 2011, 15:37
Учитывая что разница между структурой и классом не велика,что предпочтительнее?


Название: Re: Реализация класса
Отправлено: Amigo_sa от Июнь 16, 2011, 17:26
Есть мнение, что структуры предпочтительнее для "легких" классов (в значении пользовательских типов данных), в которых в основном только данные, а классы - для всех остальных вкусностей ООП. Я считаю, что вам лучше использовать структуры.


Название: Re: Реализация класса
Отправлено: time.h от Июнь 16, 2011, 20:19
Всем спасибо за помощь.


Название: Re: Реализация класса
Отправлено: lit-uriy от Июнь 17, 2011, 06:22
>>Есть мнение, что структуры предпочтительнее для "легких" классов
Я несколько раз встречал в книгах известных авторов рекомендацию:
если в структуре нужны методы, то пусть она будет классом. Если методы не нужны - то структура


Название: Re: Реализация класса
Отправлено: Igors от Июнь 17, 2011, 07:19
>>Есть мнение, что структуры предпочтительнее для "легких" классов
Я несколько раз встречал в книгах известных авторов рекомендацию:
если в структуре нужны методы, то пусть она будет классом. Если методы не нужны - то структура
Хмм... ну вот как выглядит Qt класс QPoint  (фрагмент)
Код
C++ (Qt)
class QPoint {
public:
int & rx ()
int & ry ()
void setX ( int x )
void setY ( int y )
int x () const
int y () const
....
private:
int x, y;
};
Прошу пояснить зачем меня нагрузили 6 методами? Делают они что-то полезное или только путаются под ногами в расчетах? Защиты/инкапсуляции x/y все равно никакой, т.к. есть методы возвращающие неконстантные ссылки. Мне кажется в данном конкретном случае struct была бы проще и лучше (несмотря на то что методов здесь может быть много).

По ходу дела вопрос/упражнение для начинающих: а зачем понадобились методы rx() и ry() ?


Название: Re: Реализация класса
Отправлено: Пантер от Июнь 17, 2011, 07:31
Igors, почитай Александреску "Стандарты программирования на С++", он там объясняет данный подход.


Название: Re: Реализация класса
Отправлено: Igors от Июнь 17, 2011, 08:33
Igors, почитай Александреску "Стандарты программирования на С++", он там объясняет данный подход.
Пантер, мне кажется (иногда) надо и своей головой думать, а не только следовать правилам  :)
А книга Александреску хорошая


Название: Re: Реализация класса
Отправлено: lit-uriy от Июнь 17, 2011, 09:56
Igors, в этом классе есть метод возвращающий манхэтенскую длину.
Раз уж метод есть, то класс, а не структура.

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


Название: Re: Реализация класса
Отправлено: LisandreL от Июнь 17, 2011, 10:23
Зачем используются методы вместо прямого доступа, я теряюсь в догадках.
Для единообразия.
А компилятор скорее всего всё равно (даже без подсказки) их инлайновыми сделает, так что по скорости будет тож на тож.


Название: Re: Реализация класса
Отправлено: Пантер от Июнь 17, 2011, 10:26
Зачем используются методы вместо прямого доступа, я теряюсь в догадках.
Чтобы если в дальнейшем потребуется расширение функционала, не потерять совместимости.


Название: Re: Реализация класса
Отправлено: brankovic от Июнь 17, 2011, 10:42
Зачем используются методы вместо прямого доступа, я теряюсь в догадках.
Чтобы если в дальнейшем потребуется расширение функционала, не потерять совместимости.

В одном проекте такой подход к геометрии видел. Шаблонные алгоритмы (построение остова, r-дерево) работали не только с прямоугольниками, но и с любыми объектами имеющими bounding box. При этом обычный прямоугольник тоже снабдили абсурдным на первый взгляд метеодом rect bbox () const {return *this;}. Более гибко получается, любой объект может "притвориться" точкой или прямоугольником безо всякого наследования (типа как в питоне duck typing).


Название: Re: Реализация класса
Отправлено: Авварон от Июнь 17, 2011, 11:33
Ну как бы геттеры/сеттеры защищают от тупых ошибок и для этого и нужны. rx() случайно сложно написать. И да, таки весь класс инлайнится в место использования.


Название: Re: Реализация класса
Отправлено: Igors от Июнь 17, 2011, 18:06
Ну как бы геттеры/сеттеры защищают от тупых ошибок и для этого и нужны. rx() случайно сложно написать.
Шансы перепутать rx() <-> ry() те же самые что и x <-> y  :)

В одном проекте такой подход к геометрии видел. Шаблонные алгоритмы (построение остова, r-дерево) работали не только с прямоугольниками, но и с любыми объектами имеющими bounding box. При этом обычный прямоугольник тоже снабдили абсурдным на первый взгляд метеодом rect bbox () const {return *this;}. Более гибко получается, любой объект может "притвориться" точкой или прямоугольником безо всякого наследования (типа как в питоне duck typing).
Для таких игр нужны классы "выше травы", а Point2D таким не является. Заметим что Point3D никогда не наследуется от Point2D,  так же как и "Point4D" (кватернион) от Point3D. Неудачна даже попытка запихнуть его в template, напр
Код
C++ (Qt)
template <class T>
class TPoint {
..
T x, y;
};
 
И вроде есть варианты (int, float, double) но на деле только куча неудобств  :)
Др. словами мощность такого класса слишком мала чтобы он мог что-то решать, это пассивные данные к которым все имеют прямой доступ. А если так чего тогда притворяться с get/set ? 

И дело не в том "как меньше записать" и, конечно, аксессоры никак не снизят скорость. Приятно работать с кодом где все "имеет смысл" , т.е. если человек сделал private, значит он что-то имел ввиду. А где просто налеплено get/set - логика класса не видна, и, как ни странно, эффект тот же самый что и все "public".


Название: Re: Реализация класса
Отправлено: brankovic от Июнь 17, 2011, 19:55
Для таких игр нужны классы "выше травы", а Point2D таким не является.

Вовсе нет, очень хорошо ложится на низкоуровневые классы.

это пассивные данные к которым все имеют прямой доступ. А если так чего тогда притворяться с get/set ? 

get спасает от нечаянного изменения (опечатка, = вместо ==):

Код:
if (a.x = invalid_coord)

set это имхо перебор, но тоже уменьшает вероятность неявных ошибок. Нашёл поиском сеты и видишь сразу, где объект меняли. Но я предпочитаю использовать оператор присваивания: a = point (a.x () + 10, a.y ()) вместо a.set_x (a.x () + 10). Чуть более громоздко, но наглядно.

Вообще если структура это локальная часть кода (например функтор, или внутренняя нода контейнера, или какая-нибудь деталь реализации в .cpp-файле), то делать там private/protected, set/get и прочая это блажь, имхо. Но если  класс библиотечный (как точка), используется много и в разных местах, то лучше причесать интерфейс.