Дать немного коментария по коду
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
По-моему ты невнимательно читаешь. Я же говорю, что это лучше тем, что у меня инициализация производится ОДИН раз, а у тебя ДВА раза. Инициализация должны быть вызвана однократно и только однократно, это вытекает из её определения.
ОК, давай заодно поговорим о проблемах повторной инициализации.
С системными типами данных всё хорошо. Там и в случае инициализации, и в случае присваивания вызывается один и тот же код (грубо говоря memcpy, то есть пересылка данных). Ещё для всех системных типов их деструктор ничего не делает, он пуст. Это ещё более упрощает инициализацию/присваивание.
А вот для классов всё не так. Конструктор по умолчанию (или любой другой конструктор) не должен совпадать по имплементации с оператором присваивания хотя бы потому, что в операторе присваивания должно быть уделено внимание зачистке внутреннего состояния объекта (те же действия, которые выполняются в деструкторе), а лишь потом должна быть произведена пересылка данных. Как следствие, для многих классов повторный вызов конструктора для того же самого объекта не только будет функционировать неожиданно, но вообще приведёт к крашу программы.
ОК, давай заодно поговорим о проблемах повторной инициализации.
С системными типами данных всё хорошо. Там и в случае инициализации, и в случае присваивания вызывается один и тот же код (грубо говоря memcpy, то есть пересылка данных). Ещё для всех системных типов их деструктор ничего не делает, он пуст. Это ещё более упрощает инициализацию/присваивание.
А вот для классов всё не так. Конструктор по умолчанию (или любой другой конструктор) не должен совпадать по имплементации с оператором присваивания хотя бы потому, что в операторе присваивания должно быть уделено внимание зачистке внутреннего состояния объекта (те же действия, которые выполняются в деструкторе), а лишь потом должна быть произведена пересылка данных. Как следствие, для многих классов повторный вызов конструктора для того же самого объекта не только будет функционировать неожиданно, но вообще приведёт к крашу программы.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
В данном, конкретном случае - не класс. И не надо выдумывать, что "если бы" да "кабы" там был класс. Там не класс и при инициализации там нет никакого конструктора.
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
#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" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
В том конкретном примере, поле является базовым типом. Так что все разговоры про то, что оно может быть классом относятся к категории "если бы да кабы". Да делать инициализацию в наследнике - это даже боле чем "криво". Но также "криво" присваивать в наследнике полю предка. Так что твой вариант ничем не лучше моего.
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
#define while if
Оптимизация по размеру:
#define struct union
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Airhand, снова читаешь меня не полностью или не вдумываясь. Где ты в моих постах видишь использование частиц "бы" или "б"?
Я говорю, что у системных типов есть всё, что есть у классов: конструктор по умолчанию, оператор присваивания, деструктор, операторы взятия адреса. Просто код этих сущностей таков, что повторная инициализация не рушит систему. Написание кода, который работает только потому, что нам повезло - есть признак непрофессионализма.
Теперь по поводу того, что оба подхода одинаково кривы. Здесь тоже не соглашусь. Повторное присваивание - норма, повторная инициализация - перманентный нет. Подчёркиваю, я встречался с production кодом, когда подобное присваивание использовалось потому, что иначе никак не сделать. Кстати, чаще всего присваивание поля из базового класса приходится выполнять потому, что в конструкторах нельзя вызывать виртуальные функции, иначе бы это можно было обойти. Но причины - это уже второй вопрос.
Я говорю, что у системных типов есть всё, что есть у классов: конструктор по умолчанию, оператор присваивания, деструктор, операторы взятия адреса. Просто код этих сущностей таков, что повторная инициализация не рушит систему. Написание кода, который работает только потому, что нам повезло - есть признак непрофессионализма.
Теперь по поводу того, что оба подхода одинаково кривы. Здесь тоже не соглашусь. Повторное присваивание - норма, повторная инициализация - перманентный нет. Подчёркиваю, я встречался с production кодом, когда подобное присваивание использовалось потому, что иначе никак не сделать. Кстати, чаще всего присваивание поля из базового класса приходится выполнять потому, что в конструкторах нельзя вызывать виртуальные функции, иначе бы это можно было обойти. Но причины - это уже второй вопрос.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Это всё есть в c#, а не в с++.Romeo писал(а): Я говорю, что у системных типов есть всё, что есть у классов: конструктор по умолчанию, оператор присваивания, деструктор, операторы взятия адреса.
Где я говорил, что код работает потаму, что нам повезло ? Опять выдумываеш.Просто код этих сущностей таков, что повторная инициализация не рушит систему. Написание кода, который работает только потому, что нам повезло - есть признак непрофессионализма.
Где это норма ? В "кривом" коде - да.
Теперь по поводу того, что оба подхода одинаково кривы. Здесь тоже не соглашусь. Повторное присваивание - норма, повторная инициализация - перманентный нет.
Это нарушает инкапсуляцию. Лучше уж пользоваться так называемыми Set/Get-ами. Приведи пример, где нельзя присвоить в базовом классе.Подчёркиваю, я встречался с production кодом, когда подобное присваивание использовалось потому, что иначе никак не сделать. Кстати, чаще всего присваивание поля из базового класса приходится выполнять потому, что в конструкторах нельзя вызывать виртуальные функции, иначе бы это можно было обойти. Но причины - это уже второй вопрос.
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
#define while if
Оптимизация по размеру:
#define struct union
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Это всё есть именно в С++, а не в С# (кстати, в последнем языке есть далеко не всё из выше перечисленного, я даже несколько сбит с толку твоим заявлением)" писал(а):Это всё есть в c#, а не в с++.
Ты постоянно искажаешь суть сказанного. Ты как раз не говорил, что код работает потому, что нам повезло. Это говорил я! По твоим словам двойная инициализация - это, как раз, гуд. Или нет, не так, это также криво, как и присваивание, хотя это высказывание вообще смешное. Кто нам присваивания (любое количество) запрещает делать? Есть какие-то академически мысли в пользу твоей теории?" писал(а):Где я говорил, что код работает потаму, что нам повезло ? Опять выдумываеш.
Поражаюсь твоему упорству. Ты споришь ради самого процесса?" писал(а):Где это норма ? В "кривом" коде - да.
Погоди, я не говорю, что присваивание лучше setter'а. Более того, я скажу, что setter лучше. Ты снова уходишь в сторону и ищешь новые варианты развития спора, по всей видимости получая от него удовольствие. У нас сейчас идёт эпическое обсуждение intialization vs assignment, а не assignment vs setter. Чувствуешь разницу?" писал(а):Это нарушает инкапсуляцию. Лучше уж пользоваться так называемыми Set/Get-ами. Приведи пример, где нельзя присвоить в базовом классе.
Послушай. Давай начнём с чистого листа. Есть определение инициализации, в котором сказано, что это проставление начального значения для объекта на этапе его создания. Почему ты отрицаешь очевидное: инициализация не может быть проведена дважды?
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Приветствую.
По поводу двойной инициализации...
Мой Builder 6 такое не кушает. О чём-то это говорит...
По поводу двойной инициализации...
Код: Выделить всё
class foo{
protected:
int i;
public:
foo() : i(0){}
};
class foo2 : public foo{
public:
foo2( int x ) : i(x) { }
};
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Совершенно верно, я бы это даже в стандарте запретил" писал(а):Мой Builder 6 такое не кушает. О чём-то это говорит...

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