Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.192] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 477 478 [479] 480 481 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#7171
,
|
|
|
|
Цитата jack128 @ кстати, а в плюсах компиляторы кидают какие нить варнинги/ошибки, если конструктор не все поля объекта инициализирует ?? Эммм... Такого (по идее) быть не может. Для каждого поля будет либо Default Initialization, либо инициализация, заданная пользователем (в списке инициализации). Ну а насколько default initialization соответствует инварианту класса после конструирования - это головная боль программиста. |
|
Сообщ.
#7173
,
|
|
|
|
Цитата trainer @ Он "чистенький" при условии, если 0 - это "чистенькое значение". А если нет - очень даже "грязненький". Цитата Мяут-Настоящий @ Какой смысл для таких объектов в NewInstance, который будет гарантированно возвращать невалидный объект? Во-первых, дефолтная инициализация нулями по любому лучше (по кр.мере предсказуеемее), чем случайный мусор. В дельфях она необходима, по кр.мере, для нетривиальных ссылочных мемберов (типа интерфейсов, дин.строк и дин.массивов), а также полезна для зануления всех прочих указателей (что делает возможным = более безопасным вызов деструктора в случае неполного создания объекта). Остается последний штрих к портрету - зачем связываться со сложной выборочной инициализацией, если можно быстро скопом занулить весь InstanceSize? Во-вторых, в дельфях NewInsance\InitInsance это по сути "неявный" дефолтный конструктор, наследуемый от базового предка TObject. Но в отличие от С++ он вызывается всегда перед любым другим явно определенным конструктором. Поэтому говорить об инициализации какими-то "грязными" или "невалидными" значениями тут просто неуместно - это эквиваленто тому, что сетовать на оператор new, который может выдавать либо мусор, либо зануленный кусок памяти в зависимости от реализации. Ну и, как уже отмечалось, NewInstance это виртуальный метод, который при желании можно переопределить (хотя убрать предварительное обнуление нельзя, т.к. оно сидит в невиртуальном InitInstance) |
|
Сообщ.
#7174
,
|
|
|
|
Цитата leo @ Во-первых, дефолтная инициализация нулями по любому лучше (по кр.мере предсказуеемее), чем случайный мусор. Лучше все-таки корректные данные Цитата что делает возможным = более безопасным вызов деструктора в случае неполного создания объекта Ага, создали проблему и подставили костылик Не надо вызывать деструкторы для несозданных объектов и все будет хорошо.Цитата это эквиваленто тому, что сетовать на оператор new, который может выдавать либо мусор, либо зануленный кусок памяти в зависимости от реализации. Эм. operator new отвечает за предоставление памяти требуемого размера. И ни за что больше |
|
Сообщ.
#7175
,
|
|
|
|
Цитата D_KEY @ Лучше все-таки корректные данные Это мусор на стеке или после new - корректные данные? Цитата D_KEY @ Ага, создали проблему и подставили костылик Не надо вызывать деструкторы для несозданных объектов и все будет хорошо. Возможная утечка памяти или ненужная супер-пупер инициализация чего-то - это хорошо? Или городить в сложном конструкторе многоэтажные try\except, фактически повторяющие в запутааном виде код деструктора - это тоже хорошо? Цитата D_KEY @ Эм. operator new отвечает за предоставление памяти требуемого размера. И ни за что больше 1) Предварительный вызов NewInstance не отменяет вызова явного конструктора. 2) Гепотетическая ошибка в NewInstance равносильна ошибке на стадии выделения памяти в new и на "корректность\не_корректность" вообще не созданного объекта никак не влияет |
|
Сообщ.
#7176
,
|
|
|
|
Цитата leo @ Это мусор на стеке или после new - корректные данные? Нет, корректные данные - это те, которые соответствуют инварианту сконструированного объекта. Цитата Возможная утечка памяти или ненужная супер-пупер инициализация чего-то - это хорошо? Какие утечки? Не надо руками удалять память, кроме редких специальных случаев. "супер-пупер инициализация чего-то" - это о чем? Цитата Или городить в сложном конструкторе многоэтажные try\except, фактически повторяющие в запутааном виде код деструктора - это тоже хорошо? Зачем? Ну если по другому не умеете, то да, это лучше, чем вызов деструктора для недостроенных объектов |
|
Сообщ.
#7177
,
|
|
|
|
Цитата D_KEY @ которые соответствуют инварианту сконструированного объекта. А объект к этому моменту еще и не сконструирован Цитата leo @ хотя убрать предварительное обнуление нельзя, т.к. оно сидит в невиртуальном InitInstance Можно, при желании. Никто ведь не запрещает в NewInstance вообще не вызывать дефолтный InitInstance и провести свою инициализацию на основании, скажем, атрибутов к полям. Хотя едва ли это кому-либо надо Добавлено Цитата D_KEY @ Какие утечки? Ну, создаю я в конструкторе внутренний объект... А потом происходит исключение. Мне специально предусмотреть код удаления этого объекта при исключении? А зачем? Ответсвенный за его удаление - мой сконструированный объект и именно он должен удалить его в своем деструкторе. Я на это и рассчитываю |
|
Сообщ.
#7178
,
|
|
|
|
Цитата --Ins-- @ А объект к этому моменту еще и не сконструирован Я об общей картине. Сначала зануляете поля, потом что-то меняете. У нас же сразу вызываются конструкторы полей(а те вызывают конструкторы своих полей и т.д.)... Добавлено Цитата --Ins-- @ Ну, создаю я в конструкторе внутренний объект... А потом происходит исключение. Мне специально предусмотреть код удаления этого объекта при исключении? Цитата А зачем? ![]() ![]() class A { public: A() : b(new B(10, 20, "aaa")) { throw "aaaa"; } private: unique_ptr<B> b; }; Как видишь, я вообще деструктор не пишу |
|
Сообщ.
#7179
,
|
|
|
|
Цитата D_KEY @ Сначала зануляете поля, потом что-то меняете. Да. Потому что эти действия разнесены во времени и в общем случае код InitInstance не может знать, какие значения у них должны быть. Кстати, 0/nil - корректное значение для любого типа. Но как уже сказал выше - с появлением атрибутов, можно в принципе сразу инициализировать поля нужными значениями без выноса этой инициализации в Create. Только нужно ли? Не такой уж и большой оверхид Добавлено Цитата D_KEY @ Как видишь, я вообще деструктор не пишу Потому что объект на стеке, да? |
|
Сообщ.
#7180
,
|
|
|
|
Цитата --Ins-- @ Потому что объект на стеке, да? Ты new там не видишь? Нет, объект класса B создается в динамической памяти. У тебя ссылка неявная, у меня явная(я выбрал unique_ptr, т.к. не собираюсь шарить объект). |
|
Сообщ.
#7181
,
|
|
|
|
D_KEY, ну, поздравляю. А если сделать то, что ты предлагаешь в Delphi - получишь либо утечку, либо необходимость вручную ловить исключение в конструкторе.
Добавлено В каком-то смысле, NewInstance - это BeforeConstruction, а FreeInstance - AfterDestruction. Ну в крайнем случае при необходимости можешь сам завести такие методы и вызывать их из NewInstance/FreeInstance Добавлено Цитата D_KEY @ Не надо руками удалять память Вот и правильно, и не надо руками, деструктор за конструктором все сам почистит |
|
Сообщ.
#7182
,
|
|
|
|
Цитата MyNameIsIgor @ некоторые тонкости жесть. про new T() Цитата Если конструктор по умолчанию задан явно, то будет вызван только он, и вся ответственность за инициализацию ляжет на него. то есть ![]() ![]() struct test { test() {} std:string s; } auto t = new test(); в t->s будет мусор??? |
|
Сообщ.
#7183
,
|
|
|
|
Цитата jack128 @ в t->s будет мусор??? Нет. У строк дефолтный конструктор инициализирует ее пустой строкой |
|
Сообщ.
#7184
,
|
|
|
|
Цитата OpenGL @ Нет. У строк дефолтный конструктор инициализирует ее пустой строкой то есть требуется инициализация только POD типов ? |
|
Сообщ.
#7185
,
|
|
|
|
Цитата jack128 @ то есть требуется инициализация только POD типов ? Да. |