Страница 3 из 3
Re: Дать немного коментария по коду
Добавлено: 18 май 2009, 16:40
Romeo
По-моему ты невнимательно читаешь. Я же говорю, что это лучше тем, что у меня инициализация производится ОДИН раз, а у тебя ДВА раза. Инициализация должны быть вызвана однократно и только однократно, это вытекает из её определения.
ОК, давай заодно поговорим о проблемах повторной инициализации.
С системными типами данных всё хорошо. Там и в случае инициализации, и в случае присваивания вызывается один и тот же код (грубо говоря memcpy, то есть пересылка данных). Ещё для всех системных типов их деструктор ничего не делает, он пуст. Это ещё более упрощает инициализацию/присваивание.
А вот для классов всё не так. Конструктор по умолчанию (или любой другой конструктор) не должен совпадать по имплементации с оператором присваивания хотя бы потому, что в операторе присваивания должно быть уделено внимание зачистке внутреннего состояния объекта (те же действия, которые выполняются в деструкторе), а лишь потом должна быть произведена пересылка данных. Как следствие, для многих классов повторный вызов конструктора для того же самого объекта не только будет функционировать неожиданно, но вообще приведёт к крашу программы.
Re: Дать немного коментария по коду
Добавлено: 19 май 2009, 12:13
Airhand
В данном, конкретном случае - не класс. И не надо выдумывать, что "если бы" да "кабы" там был класс. Там не класс и при инициализации там нет никакого конструктора.
Re: Дать немного коментария по коду
Добавлено: 19 май 2009, 13:03
Romeo
Ошибаешься, конструктор есть, и оператор присваивания тоже есть. Более того, есть даже операторы взятия адреса (один константный, другой не константный). То, что ты их не объявлял, это не значит, что их нет. А неправильное их использование исходя только из того, что "так ведь работает", выставляет программиста не с лучшей стороны.
Я ничего не выдумываю и не использую термины "если бы" да "кабы". Помещение поля базового класса в список инициализации в конструкторе в классе наследнике является грубой ошибкой и свидетельствует о плохой культуре программирования и плохом представлении о том, что происходит на самом деле и как работает компилятор.
Две инициализации быть не должно и точка!
Re: Дать немного коментария по коду
Добавлено: 19 май 2009, 13:26
Airhand
В том конкретном примере, поле является базовым типом. Так что все разговоры про то, что оно может быть классом относятся к категории "если бы да кабы". Да делать инициализацию в наследнике - это даже боле чем "криво". Но также "криво" присваивать в наследнике полю предка. Так что твой вариант ничем не лучше моего.
Re: Дать немного коментария по коду
Добавлено: 19 май 2009, 14:41
Romeo
Airhand, снова читаешь меня не полностью или не вдумываясь. Где ты в моих постах видишь использование частиц "бы" или "б"?
Я говорю, что у системных типов есть всё, что есть у классов: конструктор по умолчанию, оператор присваивания, деструктор, операторы взятия адреса. Просто код этих сущностей таков, что повторная инициализация не рушит систему. Написание кода, который работает только потому, что нам повезло - есть признак непрофессионализма.
Теперь по поводу того, что оба подхода одинаково кривы. Здесь тоже не соглашусь. Повторное присваивание - норма, повторная инициализация - перманентный нет. Подчёркиваю, я встречался с production кодом, когда подобное присваивание использовалось потому, что иначе никак не сделать. Кстати, чаще всего присваивание поля из базового класса приходится выполнять потому, что в конструкторах нельзя вызывать виртуальные функции, иначе бы это можно было обойти. Но причины - это уже второй вопрос.
Re: Дать немного коментария по коду
Добавлено: 19 май 2009, 15:07
Airhand
Romeo писал(а):
Я говорю, что у системных типов есть всё, что есть у классов: конструктор по умолчанию, оператор присваивания, деструктор, операторы взятия адреса.
Это всё есть в c#, а не в с++.
Просто код этих сущностей таков, что повторная инициализация не рушит систему. Написание кода, который работает только потому, что нам повезло - есть признак непрофессионализма.
Где я говорил, что код работает потаму, что нам повезло ? Опять выдумываеш.
Теперь по поводу того, что оба подхода одинаково кривы. Здесь тоже не соглашусь. Повторное присваивание - норма, повторная инициализация - перманентный нет.
Где это норма ? В "кривом" коде - да.
Подчёркиваю, я встречался с production кодом, когда подобное присваивание использовалось потому, что иначе никак не сделать. Кстати, чаще всего присваивание поля из базового класса приходится выполнять потому, что в конструкторах нельзя вызывать виртуальные функции, иначе бы это можно было обойти. Но причины - это уже второй вопрос.
Это нарушает инкапсуляцию. Лучше уж пользоваться так называемыми Set/Get-ами. Приведи пример, где нельзя присвоить в базовом классе.
Re: Дать немного коментария по коду
Добавлено: 19 май 2009, 17:04
Romeo
" писал(а):Это всё есть в c#, а не в с++.
Это всё есть именно в С++, а не в С# (кстати, в последнем языке есть далеко не всё из выше перечисленного, я даже несколько сбит с толку твоим заявлением)
" писал(а):Где я говорил, что код работает потаму, что нам повезло ? Опять выдумываеш.
Ты постоянно искажаешь суть сказанного. Ты как раз не говорил, что код работает потому, что нам повезло. Это говорил я! По твоим словам двойная инициализация - это, как раз, гуд. Или нет, не так, это также криво, как и присваивание, хотя это высказывание вообще смешное. Кто нам присваивания (любое количество) запрещает делать? Есть какие-то академически мысли в пользу твоей теории?
" писал(а):Где это норма ? В "кривом" коде - да.
Поражаюсь твоему упорству. Ты споришь ради самого процесса?
" писал(а):Это нарушает инкапсуляцию. Лучше уж пользоваться так называемыми Set/Get-ами. Приведи пример, где нельзя присвоить в базовом классе.
Погоди, я не говорю, что присваивание лучше setter'а. Более того, я скажу, что setter лучше. Ты снова уходишь в сторону и ищешь новые варианты развития спора, по всей видимости получая от него удовольствие. У нас сейчас идёт эпическое обсуждение intialization vs assignment, а не assignment vs setter. Чувствуешь разницу?
Послушай. Давай начнём с чистого листа. Есть определение инициализации, в котором сказано, что это проставление начального значения для объекта на этапе его создания. Почему ты отрицаешь очевидное: инициализация не может быть проведена дважды?
Re: Дать немного коментария по коду
Добавлено: 19 май 2009, 17:05
Rycharg
Приветствую.
По поводу двойной инициализации...
Код: Выделить всё
class foo{
protected:
int i;
public:
foo() : i(0){}
};
class foo2 : public foo{
public:
foo2( int x ) : i(x) { }
};
Мой Builder 6 такое не кушает. О чём-то это говорит...
Re: Дать немного коментария по коду
Добавлено: 19 май 2009, 17:23
Romeo
" писал(а):Мой Builder 6 такое не кушает. О чём-то это говорит...
Совершенно верно, я бы это даже в стандарте запретил

Однако на данный момент (если не ошибаюсь) этот пункт в стандарте строго не оговорен, и потому некоторые много о себе мнящие компиляторы разрешают это делать, что, порой, приводит к плачевным результатам. Я когда-то с таким сталкивался на AIX 5.1, vacpp compiler (не помню версию). Современные компиляторы, в том числе и AIX 6.1 xlc, не говоря уже о MS VC++, такие попытки пресекают на корню.