Страница 2 из 3

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

Добавлено: 15 май 2009, 17:32
Romeo
Код и терминология не верны в корне.

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

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

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. Если этот метод действительно меняет поля класса (а его имя это подразумевает), то такой код просто не скомпилируется.

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

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

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

ThreeRoom() : OneRoom(), count_room(3) {}
Ты почти всё неверно понял.

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

Добавлено: 16 май 2009, 12:06
Romeo

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

ThreeRoom() : OneRoom(), count_room(3) {}
Этот вариант ещё хуже, так как мы попытаемся провести инициализацию дважды (первый раз поле было инициализировано в конструкторе базового класса). Есть железное правило, нарушение которого чревато всевозможными неприятностями: в списке инициализации конструктора помимо вызова конструкторов базовых классов должна проводится инициализация ТОЛЬКО полей самого класса.

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

Добавлено: 17 май 2009, 11:55
Airhand
Я же сказал, что это "криво".

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

Добавлено: 18 май 2009, 11:17
Romeo
Это понятно, что криво. Просто ты написал "даже", что подразумевает, что твой вариант лучше. На самом деле он хуже, так как делает повторную инициализацию, в то время, как проставление значения в теле конструктора является не инициализацией, а присваиванием, потому, хоть такой код и не блещет изысками, он, тем не менее, является допустимым и даже используется в production code некоторых случаях, когда иначе никак нельзя :)

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

Добавлено: 18 май 2009, 12:39
Airhand
Мой вариант лучше, т.к. инициализация всё равно происходит. Зачем это делать дважды ? Ты, наверно, думаеш, что если переменной нет в списке инициализации, то она и не инициализируется. Должен тебя разочаровать: ты ошибаешся, она инициализируется.

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

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

Я вернусь через час и мы можем продолжить дискуссию, рассмотрев что именно происходит, если указать в списке инициализации поле родительского класса и чем это чревато.

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

Добавлено: 18 май 2009, 13:21
Airhand
Базовый класс как-то инмциализуруется ? В данной ситуации, что происходит ?
--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
Хоть так 2 раза, хоть так.

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

Добавлено: 18 май 2009, 14:34
Romeo
В твоём случае происходит инициализация два раза, в моём же случае первый раз происходит инициализация (в конструкторе базового класса), а во второй раз присваивание (в теле текущего класса). Это абсолютно разные вещи. Что плохого в двойной инициализации, надеюсь, не нужно объяснять?

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

Добавлено: 18 май 2009, 15:43
Airhand
В твоём случае тоже происходит инициализация, когда конструируется базовый класс в наследном. А потом ещё присваиванме в наследнике. Чем это лучше того варианта, что я описал ?