Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Конструктор и деструктор

4.9K
03 июля 2008 года
efferson
57 / / 08.12.2005
День добрый! Столкнулся с такой проблемой: у меня есть класс, конструктор которого при инициализации обрабатывает некоторые данные (присваивает их privat'ным атрибутам). Мне нужно сделать проверку данных, такую что в случае, когда данные имеют неверный формат, класс не создавался, а конструктор возвращал null. Такое вообще возможно?
3
03 июля 2008 года
Green
4.8K / / 20.01.2000
Тебе нужна фабрика объектов.
4.9K
04 июля 2008 года
efferson
57 / / 08.12.2005
Ты имеешь в виду, что стоит сделать класс, который будет отвечать за создание других классов?
3
04 июля 2008 года
Green
4.8K / / 20.01.2000
Цитата: efferson
Ты имеешь в виду, что стоит сделать класс, который будет отвечать за создание других классов?


Функцию или класс, который будет отвечать за создание экземпляров другого класса.

40K
15 июля 2008 года
xDragon
6 / / 15.07.2008
efferson в паскале была такая фишка - достаточно было из конструктора вызвать процедуру Fail. Насчёт других языков сильно сомневаюсь, наверное действительно единственный выход - фабрика.
16K
15 июля 2008 года
OlbanyRok
75 / / 14.07.2007
Вообще-то по уму вообще все объекты через фабрики создавать нужно. Гораздо гибче.
63
15 июля 2008 года
Zorkus
2.6K / / 04.11.2006
Зачем все то?
255
16 июля 2008 года
Dart Bobr
1.4K / / 09.04.2004
Цитата: OlbanyRok
Вообще-то по уму вообще все объекты через фабрики создавать нужно. Гораздо гибче.



Ага, а для создания фабрик использовать фабрики фабрик и т.д.

14
16 июля 2008 года
Phodopus
3.3K / / 19.06.2008
достаточно в конструкторе вызвать исключение
3
16 июля 2008 года
Green
4.8K / / 20.01.2000
Цитата: Phodopus
достаточно в конструкторе вызвать исключение


Этого далеко не достаточно.
Так же нужно будет внимательно проследить за освобождением ресурсов (для этого лучше использовать smartpointer-ы), обернуть вызов конструктора в блог try/catch.
А как быть, если пользователь (по ошибке) создаст (попытается) объект в статической памяти?

Короче, способ имеет право на жизнь, но IMHO сопряжен с дополнительными проблемами.

241
16 июля 2008 года
Sanila_san
1.6K / / 07.06.2005
Цитата: Green
Этого далеко не достаточно.
Так же нужно будет внимательно проследить за освобождением ресурсов (для этого лучше использовать smartpointer-ы), обернуть вызов конструктора в блог try/catch.
А как быть, если пользователь (по ошибке) создаст (попытается) объект в статической памяти?

В дотнете такое решение будет работать достаточно неплохо. :) Правда, там это работает за счёт высокого уровня абстракции.

255
16 июля 2008 года
Dart Bobr
1.4K / / 09.04.2004
Цитата: Sanila_san
В дотнете такое решение будет работать достаточно неплохо. :) Правда, там это работает за счёт высокого уровня абстракции.



неуверен, что это хорошее решение. Это может быть приемлемым способом(если конечно, эта исключительная ситуация нормально обрабатывается), только тогда, когда программа знает как вести себя в этом случае. Например, если я разрабатываю к примеру игру, и получил исключение при инициализации класса
CResourceManager, то единственный выход - завершить всё, и написать соотв. запись в лог. Но, во многих случаях, возможно изменение поведения программы даст другой результат. И намного удобнее, обработку всяких таких ситуаций возложить на плечи отдельного класса, чем рассеивать по коду. Так, что по-моему уровень абстакции, здесь не особо влияет на элегантность решения.

14
16 июля 2008 года
Phodopus
3.3K / / 19.06.2008
В дельфи незавершившийся конструктор вызывает деструктор, а try/catch/finally использовать необходимо всегда. Какая разница, вернет тебе конструктор исключение или фабрика NULL, ситуация-то исключительная и обрабатывать ее по-любому надо..

Хотя, статических объектов в дельфине конечно нету..
255
16 июля 2008 года
Dart Bobr
1.4K / / 09.04.2004
Цитата: Phodopus
В дельфи незавершившийся конструктор вызывает деструктор, а try/catch/finally использовать необходимо всегда. Какая разница, вернет тебе конструктор исключение или фабрика NULL, ситуация-то исключительная и обрабатывать ее по-любому надо..

Хотя, статических объектов в дельфине конечно нету..



Разница огромная. Или спроэктировать один класс нормально, или искать баги по всей программе.

14
16 июля 2008 года
Phodopus
3.3K / / 19.06.2008
А какой класс предлагается нормально спроектировать?
Если фабрику, то все-равно ее ошибки нужно анализировать
255
16 июля 2008 года
Dart Bobr
1.4K / / 09.04.2004
и что по-твоему элегантней проверить ошибки фабрики + добавить ей нормальную обработку ошибок классов, которые она порождает или при каждом создании такого класса делать проверку вручную? :)
3
16 июля 2008 года
Green
4.8K / / 20.01.2000
Цитата: Phodopus
В дельфи незавершившийся конструктор вызывает деструктор,


Что-то очччень сомневаюсь...
Как можно вызывать деструктор несозданного объекта?
Деструкторы должны вызываться только для инициализированных полей класса, но не для всего класса.
А так можно делов таких натворить! Например, освободить память по неинициализированному указателю.

Цитата: Phodopus

а try/catch/finally использовать необходимо всегда.


Кто тебе такое сказал?
Я вот наоборот стараюсь обходиться без них (см. недавнюю тему http://forum.codenet.ru/showthread.php?t=49265&page=5)

Цитата: Phodopus

Какая разница, вернет тебе конструктор исключение или фабрика NULL,


Разница огромная.
Хотя бы потому, что NULL возвращается, а исключение выбрасывается (вызывается).

Цитата: Phodopus

ситуация-то исключительная и обрабатывать ее по-любому надо..


Исключительная ситуация только с исключением, а с NULL - это вовсе не "исключительная ситуация"

Цитата: Phodopus

Если фабрику, то все-равно ее ошибки нужно анализировать


Что значит "ее ошибки" ? И зачем их анализировать?
Не смогла (не захотела) фабрика создавать объект, - вернула NULL. Это не ошибка фабрики! Это результат (нулевой) её работы.
В принципе, ничего анализировать не надо. Кроме обычной проверки указателя на ненулевое значение, которое и так надо делать.

А вот с исключениями хорошо бы проанализировать: что за исключение, почему возникло.

5
16 июля 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: Green
Что-то очччень сомневаюсь...
Как можно вызывать деструктор несозданного объекта?

Такая вот интересная фигня в делфи. Там и поля объекта сразу проинициализированы - нулями.

3
16 июля 2008 года
Green
4.8K / / 20.01.2000
Цитата: hardcase
Такая вот интересная фигня в делфи. Там и поля объекта сразу проинициализированы - нулями.


"Сразу" не бывает. Тогда для чего конструктор, если все уже проинициализировано "сразу".
А если поле - не POD объект? Чем он "сразу" проинициализирован?

В любом случае вызывать деструктор невалидного объекта - это опасно.

5
16 июля 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: Green
Чем он "сразу" проинициализирован?

Нулями, такими вот: 0x00. А разрушение недосозданного объекта действительно косяк в делфи. Одно из средств защиты - это использование метода Free, для разрушения объекта, он проверят на nil (NULL) значение Self указателя (this).

14
17 июля 2008 года
Phodopus
3.3K / / 19.06.2008
Чтож господа, я конечно понимаю что "out of memory" в нынешних компиляторах из области фантастики но все же.. Что, никто динамическую память в конструкторах не выделяет? Или вы заставляете фабрику выделять память и передаете ее конструктору? Нарушаете принципы инкапсуляции проверяя данные класса в фабрике? Изменение класса приводит к изменению кода фабрики..
Цитата: Green
Исключительная ситуация только с исключением, а с NULL - это вовсе не "исключительная ситуация"


Да я ж не терминологию обсуждаю - я про то что в любом случае нужно будет вставить обработчик возникшей ошибки. Возникшей ошибки создания класса, которую вернет фабрика. Конечно же это не ошибка фабрики, но раз фабрика только для того и существует, можно обозвать это ее ошибкой :)

Цитата: Green


:D начинаю понимать почему спольского турнули из майкрософта!
Для тех кто пользуется компиляторами от майкрософт могу только сказать что в свое время дизассембрировав код трех майкрософтовских программ увидел что каждая функция у них начинаеся с "глобального" try (кавычки чтоб не было споров по поводу терминологии :D). Конечно 3 программы от такого гиганта - капля в море, но все же их программисты (многие) - пишут так. Для своей системы на своих компиляторах. Даже драйвера. К сожалению про юниксы и маки ничего не скажу :( - подходы там разные. Кстати try/except ловит и ошибки ОС типа обращения по невыделеному адресу, но я думаю это все знают.
Можете глянуть на конструктор MFC::CFile, тот что с параметрами - честно предупреждают что вызывает исключение. Кстати расскажите, как с этим в .NET?

Цитата: hardcase
А разрушение недосозданного объекта действительно косяк в делфи


Да может и не косяк.. Код деструктора-то обычно небольшой, можно и на nil-ы проверить. Но документации по такому поведению я правда не видел! Хотя не скажу чтобы уж очень я ее читал : )

Ну а вообще для таких случаев люди обычно не парятся, а используют bool Init(). Пусть это не столь элегантно но.. работает

255
17 июля 2008 года
Dart Bobr
1.4K / / 09.04.2004
Цитата: Phodopus
Чтож господа, я конечно понимаю что "out of memory" в нынешних компиляторах из области фантастики но все же.. Что, никто динамическую память в конструкторах не выделяет? Или вы заставляете фабрику выделять память и передаете ее конструктору? Нарушаете принципы инкапсуляции проверяя данные класса в фабрике? Изменение класса приводит к изменению кода фабрики..


Представьте себе, что никто. Если нужно выделить память, то это делается проще. А именно создается специально метод Init(); для этой цели и метод Destroy(); для освобождения памяти. И объект получается очень даже гибко управляемым.

Цитата: Phodopus

Да я ж не терминологию обсуждаю - я про то что в любом случае нужно будет вставить обработчик возникшей ошибки. Возникшей ошибки создания класса, которую вернет фабрика. Конечно же это не ошибка фабрики, но раз фабрика только для того и существует, можно обозвать это ее ошибкой :)


Единственная "ошибка", которую может вернуть фабрика - это ничего не вернуть. Вся обработка почему, как и зачем - описывается один раз в теле фабрики, а не каждый раз при попытке создания объекта вручную.

Цитата: Phodopus

:D начинаю понимать почему спольского турнули из майкрософта!
Для тех кто пользуется компиляторами от майкрософт могу только сказать что в свое время дизассембрировав код трех майкрософтовских программ увидел что каждая функция у них начинаеся с "глобального" try (кавычки чтоб не было споров по поводу терминологии :D). Конечно 3 программы от такого гиганта - капля в море, но все же их программисты (многие) - пишут так. Для своей системы на своих компиляторах. Даже драйвера. К сожалению про юниксы и маки ничего не скажу :( - подходы там разные.


Флуд, и не относится к теме.

Цитата: Phodopus

Да может и не косяк.. Код деструктора-то обычно небольшой, можно и на nil-ы проверить. Но документации по такому поведению я правда не видел! Хотя не скажу чтобы уж очень я ее читал : )


Обычно небольшой.. Это у вас он обычно небольшой. К тому же удалять невыделеный объект противоречит логике. И эта нелогичность добавляет геморра программисту.

Цитата: Phodopus

Ну а вообще для таких случаев люди обычно не парятся, а используют bool Init(). Пусть это не столь элегантно но.. работает


Да-да-да, это работает, и достаточно элегантно и управляемо.

14
17 июля 2008 года
Phodopus
3.3K / / 19.06.2008
Цитата: Dart Bobr
Единственная "ошибка", которую может вернуть фабрика - это ничего не вернуть.


Мда? А обрабатывать это ничего дядя будет? :D

Цитата: Dart Bobr
Обычно небольшой.. Это у вас он обычно небольшой.


Если у вас он слишком большой - вы прохо спроектировали класс, уважаемый

Цитата: Dart Bobr
К тому же удалять невыделеный объект противоречит логике. И эта нелогичность добавляет геморра программисту.


А никто и не говорил что удаляет невыделенные объекты, это про что?

Цитата: Dart Bobr
Да-да-да, это работает, и достаточно элегантно и управляемо.


Нет, не элегантно

Цитата: Dart Bobr
Флуд, и не относится к теме.


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

3
17 июля 2008 года
Green
4.8K / / 20.01.2000
Цитата: Phodopus
Или вы заставляете фабрику выделять память и передаете ее конструктору? Нарушаете принципы инкапсуляции проверяя данные класса в фабрике? Изменение класса приводит к изменению кода фабрики..


Мы то инкапсуляцию не нарушаем, мы используем init().

Цитата: Phodopus

Ну а вообще для таких случаев люди обычно не парятся, а используют bool Init(). Пусть это не столь элегантно но.. работает


Это нормально.

Цитата: Phodopus

Нет, не элегантно


Факты?

Цитата: Phodopus

Да я ж не терминологию обсуждаю - я про то что в любом случае нужно будет вставить обработчик возникшей ошибки. Возникшей ошибки создания класса, которую вернет фабрика. Конечно же это не ошибка фабрики, но раз фабрика только для того и существует, можно обозвать это ее ошибкой


Цитата: Phodopus
Мда? А обрабатывать это ничего дядя будет?


Ты пытаешься использовать фабрику в своем варианте без нее с внешней обработкой ошибки. А зачем?
Возникшие при создании объекта проблемы фабрика и обработает. Внешний код лишь либо получает, либо не получает объект.

Цитата: Phodopus

начинаю понимать почему спольского турнули из майкрософта!


А с чего ты взял, что его "турнули"? Факты, пожалуйста.
А ты до сих пор паботаешь в MS ? :)
Вместо Спольски?
P.S. Спольски, а не спольского. Кроме того иностранные фамилии не склоняются.

Цитата: Phodopus

Для тех кто пользуется компиляторами от майкрософт могу только сказать что в свое время дизассембрировав код трех майкрософтовских программ увидел что каждая функция у них начинаеся с "глобального" try (кавычки чтоб не было споров по поводу терминологии :D). Конечно 3 программы от такого гиганта - капля в море, но все же их программисты (многие) - пишут так.
Для своей системы на своих компиляторах. Даже драйвера.


Ну что сказать... дурацкий какой-то аргумент... ничем не подкрепленный... да ещё и не по теме...
Ну микроскопом ещё люди пользуются... но не везде... хотя в трех лабораториях, где я был, он был. :D

Цитата: Phodopus

К сожалению про юниксы и маки ничего не скажу - подходы там разные.


К чему подходы разные? К чему тут вообще маки и юниксы?

Цитата: Phodopus

Кстати try/except ловит и ошибки ОС типа обращения по невыделеному адресу, но я думаю это все знают.


Слава богу, что не все... Ты путаешь разные исключения: "языковые" и SEH.
Желательно в этом разбираться прежде, чем лезть в спор.

Цитата: Phodopus

Можете глянуть на конструктор MFC::CFile, тот что с параметрами - честно предупреждают что вызывает исключение.


Ой, не знаю такой библиотеки... :)
Давай что-то более известное.

Цитата: Phodopus

Да может и не косяк.. Код деструктора-то обычно небольшой, можно и на nil-ы проверить. Но документации по такому поведению я правда не видел! Хотя не скажу чтобы уж очень я ее читал


Да при чем тут размер кода деструктора и nil-ы ?
Косяк может и в одной строке уместиться преспокойно. И не обязательно твоего деструктора, а и деструктора родительского класса, или одного из полей твоего класса.

255
18 июля 2008 года
Dart Bobr
1.4K / / 09.04.2004
Цитата: Phodopus
Если у вас он слишком большой - вы прохо спроектировали класс, уважаемый


Вот это да. А я всегда думал, что проэктировать следует класс = сущность. Ах нет же, оказывается, он не может быть слишком большим. Вот незадача.

Цитата: Phodopus

А никто и не говорил что удаляет невыделенные объекты, это про что?

про дельфи-подход.

Цитата: Phodopus

Нет, не элегантно


А бросать исключения в конструкторах и потом их отлавливать значит по-вашему элегантней..

Цитата: Phodopus

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


Уважаемый, сходил, посмотрел, и даже вам процитирую:

Цитата:

Флуд, или редко флад (от англ. flood /flʌd/ — «наводнение») — пустословие, сообщения в интернет-форумах и чатах, занимающие (во многих случаях) большие объёмы, либо наоборот — состоящие из одного слова или нескольких символов, и не несущие какой-либо новой, полезной или смысловой информации.

. Абсолютно уместное слово в данной ситуации.

14
18 июля 2008 года
Phodopus
3.3K / / 19.06.2008
Цитата: Green

Факты?


Ух не хотел до цитирований доходить.. : )

Цитата:
7. КОНСТРУКТОР И ПЕРЕГРУЖЕННЫЕ ФУНКЦИИ.
Использование функций типа set_date для инициализации объектов класса не элегантно и чревато ошибками. Так как нигде не утверждается, что объект должен быть инициализирован; программист может забыть сделать это или часто с равно плачевным результатом, сделать это дважды. Лучший подход состоит в том, чтобы позволить программисту объявить функцию явно предназначенную для инициализации объекта. Так как такая функция конструирует значения данного типа, он называется конструктором данного класса и опознается в языке благодаря тому, что имеет то же имя, что и сам класс.


Хотя, конечно, вы можете сказать что Страуструп для вас не авторитет. Тут я не буду искать чем вам возразить..

Цитата: Green

Внешний код лишь либо получает, либо не получает объект.


:eek: .. Да я ж про то что все равно обработку во внешнем коде ставить надо - получил он этот объект или не получил. Нет, естественно простого сравнения достаточно и исключения не потребуются, но обработка все-равно будет! Вот если бы фабрика вообще избавляла от необходимости писать доп. код обработки ошибок, цены б ей не было.

Цитата: Green

А с чего ты взял, что его "турнули"? Факты, пожалуйста. А ты до сих пор паботаешь в MS ? : ) Вместо Спольски?
P.S. Спольски, а не спольского. Кроме того иностранные фамилии не склоняются.


Это была шутка (хотя иногда склонен так думать, читая его статьи/книгу). Там был смайлик. Нет, не везде где я ставлю смайлик я шучу :) Я там никогда не работал и врядли буду. Польская (вроде бы) фамилия, действительно в русском не склоняется, и я это знаю, я ее еще и с маленькой написал. Просто у меня двоякое отношение к этому автору (могу объяснить, но где-нить в Общалке - работал с его системами), поэтому я его так русифицировал. Смит, Бонд, Джонсон (например) склоняются, если пишутся по-русски.

Цитата: Green

ничем не подкрепленный


могу посоветовать хороший дизасм :)

Цитата: Green

К чему подходы разные? К чему тут вообще маки и юниксы?


Используются другие компиляторы, куча разработчиков (модулей системы) каждый из которых выражает свою точку зрения на написание кода в целом и инициализации классов в частности. А многие учатся по их исходным кодам (на кого же равняться как не на разработчиков системы для которой пишешь) и начинают делать так же. В винде майкрософтовцы имеют корпоративные стандарты написания кода и те небольшие обрывки которые нам удается видеть "стандартны".

Цитата: Green
Слава богу, что не все... Ты путаешь разные исключения: "языковые" и SEH.
Желательно в этом разбираться прежде, чем лезть в спор.


Вспомни как ловятся ошибки чтения/записи диска при использовании MMF.

Цитата: Green

Ой, не знаю такой библиотеки...
Давай что-то более известное.


Давай. Но я не знаю что знаешь ты : ) Давай TFileStream?

Цитата: Green

Да при чем тут размер кода деструктора и nil-ы ?


Ну это я hardcase написал. Про дельфи. Я незнаю, знаете ли вы что это такое :), но там в деструкторе _лучше_ проверять поля класса перед их уничтожением, если в констукторе возможен эксепшн

Цитата: Dart Bobr

А бросать исключения в конструкторах и потом их отлавливать значит по-вашему элегантней..


Нисколько. Я не знаю ни одного элегантного метода обработки ошибок в тех языках которыми владею. Хотя.. в ассемблере все элегантно : ), ибо не отличишь одно от другого. Если знаете - подскажите, буду по гроб жизни благодарен, но чутье подсказывает мне что такого нет

Цитата: Dart Bobr

не несущие какой-либо новой, полезной или смысловой информации


тоесть все что я говорю вы давно знали?

255
18 июля 2008 года
Dart Bobr
1.4K / / 09.04.2004
Цитата: Phodopus
Хотя, конечно, вы можете сказать что Страуструп для вас не авторитет. Тут я не буду искать чем вам возразить..

Для меня Мейерс является большим авторитетом, чем Страуструп. И вот, что он пишет:

Цитата:

Не позволяйте исключениям покидать деструкторы.


К тому же Страуструп был прав, и Мейерс прав в этом случае(и они не противоречат друг-другу), так как код получается чем-то вроди:

Код:
class example
{
public:
  example()
  {
    onInitError = Init();
  }
  int Init()
  {
  };
private:
  int onInitError;
}

Как по мне - очень даже элегантное решение.

Цитата: Phodopus

:eek: .. Да я ж про то что все равно обработку во внешнем коде ставить надо - получил он этот объект или не получил. Нет, естественно простого сравнения достаточно и исключения не потребуются, но обработка все-равно будет! Вот если бы фабрика вообще избавляла от необходимости писать доп. код обработки ошибок, цены б ей не было.


А если б она за вас еще б и код писала - то ваще ваще цены б ей не было. Фабрика нужна только для того, чтобы изменять поведение программы, в зависимости от полученой исключительной ситуации.

Цитата: Phodopus

Это была шутка (хотя иногда склонен так думать, читая его статьи/книгу). Там был смайлик. Нет, не везде где я ставлю смайлик я шучу :) Я там никогда не работал и врядли буду. Польская (вроде бы) фамилия, действительно в русском не склоняется, и я это знаю, я ее еще и с маленькой написал. Просто у меня двоякое отношение к этому автору (могу объяснить, но где-нить в Общалке - работал с его системами), поэтому я его так русифицировал. Смит, Бонд, Джонсон (например) склоняются, если пишутся по-русски.


шутник, а еще обижаетесь, что я назвал эту "шутку" флудом..

Цитата: Phodopus

Нисколько. Я не знаю ни одного элегантного метода обработки ошибок в тех языках которыми владею. Хотя.. в ассемблере все элегантно : ), ибо не отличишь одно от другого. Если знаете - подскажите, буду по гроб жизни благодарен, но чутье подсказывает мне что такого нет


смотрите выше. метод избавляет от кучи геморроя, а если классы управляются фабрикой - то это вообще сказка :)

Цитата: Phodopus

тоесть все что я говорю вы давно знали?


А вы пока ничего сверхестественного и не сказали.

З.Ы. Уважаемый, а вы бы все-таки потрудились почитать разницу между обработкой исключений при помощи SEH и нативной(С++овой) обработкой. Для ленивых - даю ссылку: http://www.devdoc.ru/index.php/content/view/seh_vs_cpp.htm Да, в MSVC одно сделано через другое, но это в общем случае неверно.

3
18 июля 2008 года
Green
4.8K / / 20.01.2000
Цитата: Phodopus

Хотя, конечно, вы можете сказать что Страуструп для вас не авторитет. Тут я не буду искать чем вам возразить..


Ох как же ты любишь додумывать за других... "Страуструп для вас не авторитет", "Нарушаете принципы инкапсуляции..."

А ответ на твою цитату Страуструпа прост: в ней ничего не говорится про фабрику. А между тем, фабрика (фабрика объектов, фабричный метод) и может быть той явно предназначенной и не только для инициализации, но и для создания и проверки созданного объекта функцией. Кроме того фабрика может не просто создать и проанализировать объект, а сделать это по-разному в зависимости от условий. Поэтому она ещё иногда и называется "виртуальным конструктором".
Отсюда нет никакой неэлегантности вызова init(), впрочем, как и др. действий с объектом, из фабрики. Фабрика для того и служит, чтоб предоставить пользователю готовый, проинициализированный объект.
Более того фабрика может быть статическим методом того же класса, что и создаваемый ею объект. При этом даже без метода init() принцип инкапсуляции не нарушается.
И ещё, обычно при использовании фабрик, исключается возможность создания экземпляра "напрямую".

Цитата: Phodopus

:eek: .. Да я ж про то что все равно обработку во внешнем коде ставить надо - получил он этот объект или не получил. Нет, естественно простого сравнения достаточно и исключения не потребуются, но обработка все-равно будет! Вот если бы фабрика вообще избавляла от необходимости писать доп. код обработки ошибок, цены б ей не было.


Ну так в чем проблема создать фабрику, которая обрабатывает ошибки создания?
И что значит "обработка все-равно будет"? Никакой дополнительной обработки может и не быть. Обычно при использовании указателей они проверяются на ненулевое значение независимо фабрикой ли был создан объект или обычным образом. Так вот этой проверки будет достаточно, ничего дополнительного можно не вводить.

Цитата: Phodopus

Это была шутка (хотя иногда склонен так думать, читая его статьи/книгу).

Просто у меня двоякое отношение к этому автору (могу объяснить, но где-нить в Общалке - работал с его системами)


Вполне адекватный автор. Что именно ты прочел и что вызвало у тебя такую реакцию?
С какими системами работал? Можешь ответить в Общалке.

Цитата: Phodopus

могу посоветовать хороший дизасм :)


При чем тут дизасм? "Я дизассемблировал ТРИ программы" - это не доказательство, да и доказательством чего это может быть?

Цитата: Phodopus

Используются другие компиляторы, куча разработчиков (модулей системы) каждый из которых выражает свою точку зрения на написание кода в целом и инициализации классов в частности. А многие учатся по их исходным кодам (на кого же равняться как не на разработчиков системы для которой пишешь) и начинают делать так же. В винде майкрософтовцы имеют корпоративные стандарты написания кода и те небольшие обрывки которые нам удается видеть "стандартны".


При чем тут компиляторы?
Зачем равняться на разработчиков ОС? Я не против них, но почему ты считаешь их истиной в "первой инстанции" и что равняться надо именно на них?
Что касается стандартов, то код MS - это такая "солянка", что говорить о стилистике можно только в конкретной части кода. Да и к чему это ("глобальные" try) в данной теме?

Цитата: Phodopus

Вспомни как ловятся ошибки чтения/записи диска при использовании MMF.


Да по разному они ловятся. Опять к чему это в данной теме?
Или ты будешь спорить, что исключения бывают разные?
В контексте топика имеются в виду исключения средствами языка, а ты съехал до SEH.

Цитата: Phodopus

Давай. Но я не знаю что знаешь ты : ) Давай TFileStream?


Я знаю STL, к примеру.

Цитата: Phodopus

Ну это я hardcase написал. Про дельфи. Я незнаю, знаете ли вы что это такое :), но там в деструкторе _лучше_ проверять поля класса перед их уничтожением, если в констукторе возможен эксепшн


И это фраза в защиту элегантности решения с исключением в конструкторе? :)

5
18 июля 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: Phodopus
Ну это я hardcase написал. Про дельфи. Я незнаю, знаете ли вы что это такое :), но там в деструкторе _лучше_ проверять поля класса перед их уничтожением, если в констукторе возможен эксепшн

Ну, в делфи у объектов есть нехилый жизненный цикл. Чего стоит последовательность:
NewInstance (выделяем память под сам объект)
Constructor
AfterConstruction
...
BeforeDestruction
Destructor
Когда метод AfterContruction зовется ТОЛЬКО при удачном завершении конструктора, а в случае исключения в конструкторе автоматом зовется деструктор, но метод а BeforeDestruction не вызывается.

А для автоматической проверки на nil есть спец метод, о котором я говорил - Free. и вариация FreeAndNil (зовет Free и ставит указатель в nil). Потому деструкторы в делфи обычно последовательность вызовов процедуры FreeAndNil для внутренних объектов.

255
18 июля 2008 года
Dart Bobr
1.4K / / 09.04.2004
hardcase, не в курсе, для билдера такая же логика как для дельфи?
11
18 июля 2008 года
oxotnik333
2.9K / / 03.08.2007
Цитата: Dart Bobr
hardcase, не в курсе, для билдера такая же логика как для дельфи?


[quote=BCB Help]
Do not call AfterConstruction in application code.
[/quote]
Аналогично с Free() и прочими паскалевскими прибабахами

14
18 июля 2008 года
Phodopus
3.3K / / 19.06.2008
Цитата: Dart Bobr
Для меня Мейерс является большим авторитетом..


Согласен, правда не делаю между ними сравнений.
Получается, что мы не сможем сделать функцию init() виртуальной? А хотелось бы. Эх нету Мейерса под рукой, дома поконсультируюсь у него :)

Цитата: Dart Bobr
А если б она за вас..


Стирала б, убирала и готовила, тогда б я вообще этого поста б не оставил :) Боюсь вот это уж точно оффтопик (мой)

Цитата: Dart Bobr
шутник, а еще обижаетесь, что я назвал эту "шутку" флудом..


ну вы бОльший кусок к флуду отнесли, вот я и приобидился

Цитата: Dart Bobr
А вы пока ничего сверхестественного и не сказали.


И не собирался : ). Но по классификации флуда получается что или мой пост "баян", или абсолютно бесполезен, или бессмысленен. Я думаю это автору топика решать?

Цитата: Dart Bobr
смотрите выше. метод избавляет от кучи геморроя..


Да это я сказал про обработку ошибок вообще, невозможность создания объекта лишь их подмножество

Цитата: Green
Ох как же ты любишь додумывать за других...


Не додумывать, а думать. Между прочим помогает за рулем, да и вообще в любом управлении (людьми, машинами, процессами). Развивает мозг, позволяет предсказывать/предугадывать ситуации. В программировании тоже оказывает немалое подспорье.

Цитата: Green
При этом даже без метода init() принцип инкапсуляции не нарушается. И ещё, обычно при использовании фабрик, исключается возможность создания экземпляра "напрямую".


Вот это действительно красиво и так сделано в Delphi, но мы налетаем на ограничения невозможности создать объект статически, за что я так люблю C++. И получается что конструктор класса-то - фактически не нужен?!

Цитата: Green
Обычно при использовании указателей они проверяются на ненулевое значение


Ура, я как раз про это. Про то что либо придется писать try..except (это Delphi) / либо if <>nil then begin, какой бы способ (фабрику или эксепшн) ты не использовал. Но try/except в создающей функции способен предохранить тебя от огромного количества ошибок сверх этой невозможности создать объект

Цитата: Green
С какими системами работал?


foxbugs. Накатаю постик на будущей недельке

Цитата: Green
"Я дизассемблировал ТРИ программы" - это не доказательство, да и доказательством чего это может быть?


Не надо так выделять мое "три". Я исследовал гораздо больше программ за свою жизнь, а эти были в одно время, все от майкрософт, и все рассматривались на предмет обработки ошибок/исключений. И я ничего не пытаюсь никому доказать, зачем мне это? Просто у всякой проблемы есть несколько способов решения и я разбираю один, а вы другой. В дискуссии мы выясняем достоинства и недостатки каждого из них, не так ли? А призыв поголовно использовать исключения или фабрики классов звучит подобно призыву верить в одного бога и, на мой взляд, неприемлем

Цитата: Green
При чем тут компиляторы? Зачем равняться на разработчиков ОС... Да и к чему это ("глобальные" try) в данной теме?


Я не говорю что надо, я говорю как происходит. Я не считаю их истиной в последней инстанции но уверен что их код создан максимально эффективно отработать на их платформе. "Глобальные" try - к тому что микрософт ими не брезгует, и что если кому-то покажется некрасивым/неэффективным/нелогичным использование исключений, пусть возьмут на заметку

Цитата: Green
Или ты будешь спорить, что исключения бывают разные? В контексте топика имеются в виду исключения средствами языка, а ты съехал до SEH.


Не съехал а напомнил что и он в них входит, что прибавляет им весомости

Цитата: Green
Я знаю STL, к примеру.


Тогда глянь кто вызывает std::exception, у меня исходников STL нет под рукой.. И не думаю что STL использует фабрики классов

Цитата: Green
И это фраза в защиту элегантности решения с исключением в конструкторе? :)


Не надо воспринимать мое "Пусть это не столь элегантно" как "Я вот вызвал бы исключение - это элегантно, а init() - совсем наоборот". Я про то что не надо париться если это покажется некрасивым

Цитата: hardcase
А для автоматической проверки на nil есть спец метод, о котором я говорил - Free


Да просто бывает я память GetMem-ом выделяю, ну и проверяю в конце if Assigned() или if <> nil then FreeMem. Объекты-то конечно Free(AndNil)

255
18 июля 2008 года
Dart Bobr
1.4K / / 09.04.2004
Цитата: Phodopus
Согласен, правда не делаю между ними сравнений.
Получается, что мы не сможем сделать функцию init() виртуальной? А хотелось бы. Эх нету Мейерса под рукой, дома поконсультируюсь у него :)


Конечно не сможем. Да и зачем? Если она нужна только(!!) для создания объекта.

5
18 июля 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: Phodopus
Получается, что мы не сможем сделать функцию init() виртуальной? А хотелось бы. Эх нету Мейерса под рукой, дома поконсультируюсь у него :)

Да, Init стоит делать виртуальным. Опыт подсказывает, что сильно это удобно.

Цитата: Phodopus
Да просто бывает я память GetMem-ом выделяю

Ну, специфика неуправляемого (unmanaged) кода. Я вот уже и забыл совсем, что такое "выделение памяти руками" и вызов деструктора. Вообще, выделение памятии маллоками или гетмамами хреновая практика - уж лучше динамические массивы.

14
18 июля 2008 года
Phodopus
3.3K / / 19.06.2008
Цитата: Dart Bobr
Да и зачем?


А если мы наследника сделаем?

14
18 июля 2008 года
Phodopus
3.3K / / 19.06.2008
Цитата: hardcase
Вообще, выделение памятии маллоками или гетмамами хреновая практика - уж лучше динамические массивы.


Куда лучше, в плане удобства, да только специфика программы такая что эффективнее делать так. То что GemMem выделяется, конечно, это я загнул - можно и динамическими, а вот то что VirtualAlloc уже никак :( Хотя бывает что и GetMem никак..

ПыСы.
Чуть ли не с первого поста забываю сказать что мы у человека компилятор и ось не спросили :)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог