![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Классы
student_92 © (2011-01-12 11:31:00)нужно ли в конструкторе вызывать inherited Create
type
TMyClass = class(TObject)
{ ... }
public
{ ... }
constructor Create(const AItemName: string);
{ ... }
end;
constructor TMyClass.Create(const AItemName: string);
begin
inherited Create; // <- ?
{ ... }
end;
Ega23 (2011-01-13 20:43:00) [41]
> Нет сценариев, в которых реинициализация дала бы преимущество
> перед повторной инстанциацией.
Полно. Сам недавно такую схему реализовывал.
DiamondShark (2011-01-13 20:25:00) [42]
> _Юрий (13.01.11 20:12) [37]
Доказать такое формально нельзя.
Потому что понятие "ощутимо снижается" не имеет формального определения.
Но можно предположить, что ощутимо сужается пространство свободы для шаловливых ручонок.
_Юрий (2011-01-13 20:12:00) [43]а кто нибудь может формально доказать, почему при стиле программирования "состояние после инициализации не меняется никогда", количество ошибок в программе ощутимо снижается?
DiamondShark (2011-01-13 18:59:00) [44]
> oxffff © (13.01.11 17:20) [35]
> У кого как.
Ни у кого ни как.
По-определению, конструктор переводит объект из состояния "Выделен" в состояние "Инициализирован", а метод реинициализации переводит объект из любогопромежуточного состояния в состояние "Инициализирован".
Иными словами, конструктор реализует одну единственную дугу графа состояний, а метод реинициализации должен реализовывать потенциально бесконечное множество дуг графа состояний. Даже в предельно примитивном случае, когда объект, кроме терминальных состояний, имеет только одно рабочее состояние, конструктор и реинициализатор реализуют разныедуги графа состояний. Даже если у тебя логика конструкции и реинициализации примитивны и вторая покравает первую, так, что тело конструктора сводится к единственному вызову реинициализатора, то это твой маленький секрет, деталь реализации, на которую клиент объекта ни в коем случае не имеет права полагаться.
Возможность вызова конструктора как метода -- это именно багофича конкретной реализации языка, появившаяся ради неусложнения компилятора. Никогда конструктор не задумывался как реинициализатор. Никакие объекты стандартной библиотеки не проектировались с возможностью использования конструктора как реинициализатора, никогда такой сценарий не документировался. Никогда такой сценарий не должен использоваться в новом дизайне, потому что нарушает привычные паттерны сложившейся практики, требует особого документирования, и, кроме вырожденных случаев, не даёт никакой экономии.
Наконец, вызывает большое сомнения сама необходимость реинициализации. Нет сценариев, в которых реинициализация дала бы преимущество перед повторной инстанциацией.
oxffff (2011-01-13 17:20:00) [45]
> DiamondShark © (13.01.11 17:00) [34]
>
> > Если два метода семантически эквивалентны
>
> Они семантически не эквивалентны.
> Они реализуют разные ветки перехода на графе состояний объекта.
>
У кого как.
DiamondShark (2011-01-13 17:00:00) [46]
> Если два метода семантически эквивалентны
Они семантически не эквивалентны.
Они реализуют разные ветки перехода на графе состояний объекта.
oxffff (2011-01-13 16:03:00) [47]
> Cobalt © (13.01.11 15:24) [32]
> Нет ничего плохого в том, чтобы забивать гвозди микроскопом
> :)
> Задача выполнена? Выполнена.
> Просто это выглядит странно.
Забивать нужно с умом.
Если два метода семантически эквивалентны, то зачем спрашивается их два, а не один?
Cobalt (2011-01-13 15:24:00) [48]Нет ничего плохого в том, чтобы забивать гвозди микроскопом :)
Задача выполнена? Выполнена.
Просто это выглядит странно.
Ega23 (2011-01-13 14:16:00) [49]
> Я бы не стал писать так. Однако ничего плохого не вижу в
> этом стиле.
Собственно, этим всё сказано.
Я бы тоже не стал. Именно по причине невозможности нормального масштабирования дерева классов.
oxffff (2011-01-13 14:13:00) [50]
> Однако ничего плохого не вижу в этом стиле.
Точнее страшного.
oxffff (2011-01-13 14:13:00) [51]
> Ega23 © (13.01.11 12:57) [28]
>
> > Я написал не про то, что так нужно делать всегда, а про
>
> > то, когда create и init идентичен по семантике и необходимости
>
> > виртуального конструктора.
>
>
> Идентичен - да.
> Хорошо, я по-другому переформулирую: ты сам бы написал такой
> код в коммерческом проекте?
Я бы не стал писать так. Однако ничего плохого не вижу в этом стиле.
Ega23 (2011-01-13 12:57:00) [52]
> Я написал не про то, что так нужно делать всегда, а про
> то, когда create и init идентичен по семантике и необходимости
> виртуального конструктора.
Идентичен - да.
Хорошо, я по-другому переформулирую: ты сам бы написал такой код в коммерческом проекте?
oxffff (2011-01-13 12:51:00) [53]
> Cobalt © (13.01.11 12:49) [26]
> 2 oxffff © (13.01.11 12:00) [21]
> В TStrings есть метод Create, а есть метод Clear
>
> Используйте нужный
Я написал не про то, что так нужно делать всегда, а про то, когда create и init идентичен по семантике и необходимости виртуального конструктора.
Cobalt (2011-01-13 12:49:00) [54]2 oxffff© (13.01.11 12:00) [21]
В TStrings есть метод Create, а есть метод Clear
Используйте нужный
oxffff (2011-01-13 12:47:00) [55]
> да, можно обойтись, код из Init передать в конструктор.
> И реинициализировать вызовом конструктора.
>
>
> constructor TFoo.Create;
> begin
> inherited;
> FListField := TList.Create;
> ... <код, перенесённый из Init>
> end;
>
> И звиздец котёнку.
Заимствую упоминаемое ИШ выражение про стеклянный ....
oxffff (2011-01-13 12:46:00) [56]
> DiamondShark © (13.01.11 12:15) [23]
>
> > Китайский вопрос. А почему?
>
> Потому что русский язык велик и могуч. И читать на нём надо
> не по диагонали. Ответ у тебя прямо перед носом:
>
> > Инициализатор из любого промежуточного состояния -- это
>
> > не конструктор, это совсем другой метод, возможно, что
> с
> > совершенно иной логикой работы.
>
> Sapienti sat.
Я лишь прочитал, что написано. Не больше, не меньше.
По остальному Вы трактуете свои слова как хотите.
Я так понимаю здесь идет намек на разницу в С++ между конструктором копий и оператором =. (на смысл этой оптимизации, отсутствие финализации lvalue)
А ничего что в Delphi в конструкторе может произойти исключение в конструкторе и вызывается деструктор, и что на самом деле есть еще newinstance который делает преинициализацию?
DiamondShark (2011-01-13 12:15:00) [57]
> Китайский вопрос. А почему?
Потому что русский язык велик и могуч. И читать на нём надо не по диагонали. Ответ у тебя прямо перед носом:
> Инициализатор из любого промежуточного состояния -- это
> не конструктор, это совсем другой метод, возможно, что с
> совершенно иной логикой работы.
Sapienti sat.
Ega23 (2011-01-13 12:07:00) [58]
> Китайский вопрос. А почему?
procedure Init; virtual; возможно abstract;
constructor TFoo.Create;
begin
inherited;
Init;
end;
да, можно обойтись, код из Init передать в конструктор. И реинициализировать вызовом конструктора.
constructor TFoo.Create;
begin
inherited;
FListField := TList.Create;
... <код, перенесённый из Init>
end;
И звиздец котёнку.
oxffff (2011-01-13 12:00:00) [59]
> DiamondShark © (13.01.11 11:51) [20]
>
> > Ведь конструктор это и есть инициализатор.
>
> Конструктор -- это конструктор, т.е. инициализаториз неинициализированного
> состояния.
> Инициализатор из любого промежуточного состояния -- это
> не конструктор, это совсем другой метод, возможно, что с
> совершенно иной логикой работы.
>
Помоему хорошо сказал в выделенном.
> Возможность вызова конструктора, как инстанс метода -- очевидная
> багофича языка, которая НИКОГДА не должна использоваться.
>
Китайский вопрос. А почему?
DiamondShark (2011-01-13 11:51:00) [60]
> Ведь конструктор это и есть инициализатор.
Конструктор -- это конструктор, т.е. инициализатор из неинициализированного состояния.
Инициализатор из любого промежуточного состояния -- это не конструктор, это совсем другой метод, возможно, что с совершенно иной логикой работы.
Возможность вызова конструктора, как инстанс метода -- очевидная багофича языка, которая НИКОГДА не должна использоваться.