Дать немного коментария по коду

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Код и терминология не верны в корне.

Код должен быть следующим:

Код: Выделить всё

class ThreeRoom: public OneRoom
{
public:
ThreeRoom() : OneRoom() { count_room = 3; }
ThreeRoom(double sqr, int flr, double sqr_kitchen) : OneRoom(sqr, flr, sqr_kitchen) { count_room = 3; }
};
Коментарии должны быть следующими:

Код: Выделить всё

ThreeRoom() : OneRoom(){ count_room = 3; }
TreeRoom - это конструктор по умолчанию (default constructor) для класса ThreeRoom. В нём вызывается конструктор базового класса OneRoom для того, чтобы проинициализировать его поля. В теле конструктора TreeRoom происходит присваивание полю count_room значения 3.

Кстати, этот подход неправильный. Поле count_room должно инициализироваться посредством конструктора того класса, в котором оно расположено, а в классе-наследнике должен вызываться конструктор. Прямое последование не только криво, так как нарушает принципы инкапсуляции, но ещё и не возможно, например в том случае, если поле count_room является private.

Помимо этих заметок я бы наделал ещё кучу замечаний, но они уже касаются не класса TreeRoom. Например в классе OneRoom есть метод SetRoomCount, причём, внимание, для не проставлен идентификатор const. Если этот метод действительно меняет поля класса (а его имя это подразумевает), то такой код просто не скомпилируется.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Airhand
Сообщения: 239
Зарегистрирован: 06 окт 2005, 16:21
Откуда: Dnepropetrovsk

Да я согласен с Romeo: присваивания count_room = 3; в конструкторе не должно быть. Это не только "криво", но и нарушает инкапсуляцию. Даже в виде:

Код: Выделить всё

ThreeRoom() : OneRoom(), count_room(3) {}
Ты почти всё неверно понял.
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Код: Выделить всё

ThreeRoom() : OneRoom(), count_room(3) {}
Этот вариант ещё хуже, так как мы попытаемся провести инициализацию дважды (первый раз поле было инициализировано в конструкторе базового класса). Есть железное правило, нарушение которого чревато всевозможными неприятностями: в списке инициализации конструктора помимо вызова конструкторов базовых классов должна проводится инициализация ТОЛЬКО полей самого класса.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Airhand
Сообщения: 239
Зарегистрирован: 06 окт 2005, 16:21
Откуда: Dnepropetrovsk

Я же сказал, что это "криво".
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Это понятно, что криво. Просто ты написал "даже", что подразумевает, что твой вариант лучше. На самом деле он хуже, так как делает повторную инициализацию, в то время, как проставление значения в теле конструктора является не инициализацией, а присваиванием, потому, хоть такой код и не блещет изысками, он, тем не менее, является допустимым и даже используется в production code некоторых случаях, когда иначе никак нельзя :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Airhand
Сообщения: 239
Зарегистрирован: 06 окт 2005, 16:21
Откуда: Dnepropetrovsk

Мой вариант лучше, т.к. инициализация всё равно происходит. Зачем это делать дважды ? Ты, наверно, думаеш, что если переменной нет в списке инициализации, то она и не инициализируется. Должен тебя разочаровать: ты ошибаешся, она инициализируется.
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Вынужден тебя разочаровать в ответ. Автоматически инициализируются (если не указаны в списки инициализации), только поля ДАННОГО класса. Это не касается полей родителя! Иначе бы у тебя происходила инициализация каждого поля ровно столько раз, какова глубина дерева иерархии, что вообще противоречит определению инициализации, как таковой.

Я вернусь через час и мы можем продолжить дискуссию, рассмотрев что именно происходит, если указать в списке инициализации поле родительского класса и чем это чревато.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Airhand
Сообщения: 239
Зарегистрирован: 06 окт 2005, 16:21
Откуда: Dnepropetrovsk

Базовый класс как-то инмциализуруется ? В данной ситуации, что происходит ?
--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
Хоть так 2 раза, хоть так.
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

В твоём случае происходит инициализация два раза, в моём же случае первый раз происходит инициализация (в конструкторе базового класса), а во второй раз присваивание (в теле текущего класса). Это абсолютно разные вещи. Что плохого в двойной инициализации, надеюсь, не нужно объяснять?
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Airhand
Сообщения: 239
Зарегистрирован: 06 окт 2005, 16:21
Откуда: Dnepropetrovsk

В твоём случае тоже происходит инициализация, когда конструируется базовый класс в наследном. А потом ещё присваиванме в наследнике. Чем это лучше того варианта, что я описал ?
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
Ответить