Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2011.04.10;
Скачать: [xml.tar.bz2];

Вниз

Классы   Найти похожие ветки 

 
student_92   (2011-01-12 11:31) [0]

нужно ли в конструкторе вызывать 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-12 11:33) [1]


> нужно ли в конструкторе вызывать inherited Create


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


 
student_92   (2011-01-12 11:35) [2]

все ясн, спасибо


 
Amoeba_   (2011-01-12 11:36) [3]

Если наследование непосредственно от TObject, то вызов конструктора предка не является обязательным.


 
Leonid Troyanovsky ©   (2011-01-12 21:47) [4]


> Ega23 ©   (12.01.11 11:33) [1]

> Идеологически - нужно всегда

Идеологически конструктору нужно быть виртуальным.


> Amoeba_   (12.01.11 11:36) [3]

> Если наследование непосредственно от TObject, то вызов конструктора
> предка не является обязательным.

И не обязательно class(TObject), можно просто - class.

--
Regards, LVT.


 
KSergey ©   (2011-01-12 22:00) [5]

В деструкторе тоже хорошо бы соотв. метод предка позвать, кстати!


 
_Юрий   (2011-01-12 22:08) [6]


> Leonid Troyanovsky ©   (12.01.11 21:47) [4]
> Идеологически конструктору нужно быть виртуальным.
>

Зачем?


 
Leonid Troyanovsky ©   (2011-01-12 22:13) [7]


> _Юрий   (12.01.11 22:08) [6]

> Зачем?

Подумать о потомках.

--
Regards, LVT.


 
Ega23 ©   (2011-01-13 00:14) [8]


> Подумать о потомках.


Не вижу причин в надобности виртуального конструктора, кроме коллекции классов (class of)
Во всех остальных случаях точно также статичный метод через inherited можно вызвать.
Тебя ведь не удивляет вызов

function TObjectList.Add(AObject: TObject): Integer;
begin
 Result := inherited Add(AObject);
end;

Никакой виртуальности, однако...


 
Ega23 ©   (2011-01-13 00:24) [9]

Или вот тоже
constructor TObjectList.Create(AOwnsObjects: Boolean);
begin
 inherited Create;
 FOwnsObjects := AOwnsObjects;
end;


 
_Юрий   (2011-01-13 00:26) [10]

некоторым аналогом виртуализации конструктора TObject является конструкция
<T: class, construtor>. Но только для случаев определения типов в компайл-тайм


 
Anatoly Podgoretsky ©   (2011-01-13 00:33) [11]

> Ega23  (13.01.2011 00:14:08)  [8]

Можно даже Result := inherited


 
KSergey ©   (2011-01-13 09:27) [12]

> Leonid Troyanovsky ©   (12.01.11 22:13) [7]
> Подумать о потомках

Потомки конкретного класса не будут конструироваться через фабрику. Никогда. Зачем о них думать? "пусть будет"?


 
oxffff ©   (2011-01-13 09:42) [13]

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

 ClassA=class
 constructor create;virtual;abstract;
 end;

 ClassB=class(ClassA)
 constructor create;override;
 end;

procedure TForm3.FormCreate(Sender: TObject);
var a:ClassA;
begin
a:=ClassB.create;
a.create;
a.free;
end;


 
Ega23 ©   (2011-01-13 10:52) [14]


> oxffff ©   (13.01.11 09:42) [13]


А в чём прикол?
Ну, в смысле, назови задачу, где вот именно такая надобность в таком изврате?


 
oxffff ©   (2011-01-13 11:05) [15]


> Ega23 ©   (13.01.11 10:52) [14]
>
> > oxffff ©   (13.01.11 09:42) [13]
>
>
> А в чём прикол?
> Ну, в смысле, назови задачу, где вот именно такая надобность
> в таком изврате?


Например переинициализация объекта без перевыделения памяти.
Например объект содержит некоторое состояние, теперь нужно перевести объект в начальное состояние без перевыделения памяти(это дорого).
Тут конечно на ум приходит отдельная procedure Initial, но если конструктор именно это и делает, то и нет надобности в отдельной Initial. Просто вызови экземпплярный конструктор.


 
oxffff ©   (2011-01-13 11:06) [16]


> oxffff ©   (13.01.11 11:05) [15]


IMHO.


 
Ega23 ©   (2011-01-13 11:07) [17]


> Тут конечно на ум приходит отдельная procedure Initial,
> но если конструктор именно это и делает, то и нет надобности
> в отдельной Initial. Просто вызови экземпплярный конструктор.


procedure   Init; virtual; возможно abstract;

constructor TFoo.Create;
begin
 inherited;
 Init;
end;


Всегда так и делал, нафига конструктор-то?


 
oxffff ©   (2011-01-13 11:16) [18]


> Ega23 ©   (13.01.11 11:07) [17]
>
> > Тут конечно на ум приходит отдельная procedure Initial,
>  
> > но если конструктор именно это и делает, то и нет надобности
>
> > в отдельной Initial. Просто вызови экземпплярный конструктор.
>
>
>
> procedure   Init; virtual; возможно abstract;
>
> constructor TFoo.Create;
> begin
>  inherited;
>  Init;
> end;
>
> Всегда так и делал, нафига конструктор-то?


Нафига init? Просто Instance.create.
Ведь конструктор это и есть инициализатор.

P.S.
Просто у него при классовом вызове добавляется аллокатор.


 
Ega23 ©   (2011-01-13 11:19) [19]


> Нафига init? Просто Instance.create.

А это к вопросу, нафига при наследовании от TObject inherited писать.
Сегодня одно, а завтра - другое. Добавится создание внутренних объектов, ещё какой-нибудь фигни.
Конструктор нужен для "выделения внутренней памяти", деструктор - для её зачистки. ИМХО.


 
DiamondShark ©   (2011-01-13 11:51) [20]


> Ведь конструктор это и есть инициализатор.

Конструктор -- это конструктор, т.е. инициализатор из неинициализированного состояния.
Инициализатор из любого промежуточного состояния -- это не конструктор, это совсем другой метод, возможно, что с совершенно иной логикой работы.

Возможность вызова конструктора, как инстанс метода -- очевидная багофича языка, которая НИКОГДА не должна использоваться.


 
oxffff ©   (2011-01-13 12:00) [21]


> DiamondShark ©   (13.01.11 11:51) [20]
>
> > Ведь конструктор это и есть инициализатор.
>
> Конструктор -- это конструктор, т.е. инициализатор из неинициализированного
> состояния.
> Инициализатор из любого промежуточного состояния -- это
> не конструктор, это совсем другой метод, возможно, что с
> совершенно иной логикой работы.
>

Помоему хорошо сказал в выделенном.


> Возможность вызова конструктора, как инстанс метода -- очевидная
> багофича языка, которая НИКОГДА не должна использоваться.
>


Китайский вопрос. А почему?


 
Ega23 ©   (2011-01-13 12:07) [22]


> Китайский вопрос. А почему?



procedure   Init; virtual; возможно abstract;

constructor TFoo.Create;
begin
inherited;
Init;
end;


да, можно обойтись, код из Init передать в конструктор. И реинициализировать вызовом конструктора.


constructor TFoo.Create;
begin
inherited;
FListField := TList.Create;  
... <код, перенесённый из Init>
end;


И звиздец котёнку.


 
DiamondShark ©   (2011-01-13 12:15) [23]


> Китайский вопрос. А почему?

Потому что русский язык велик и могуч. И читать на нём надо не по диагонали. Ответ у тебя прямо перед носом:

> Инициализатор из любого промежуточного состояния -- это
> не конструктор, это совсем другой метод, возможно, что с
> совершенно иной логикой работы.

Sapienti sat.


 
oxffff ©   (2011-01-13 12:46) [24]


> DiamondShark ©   (13.01.11 12:15) [23]
>
> > Китайский вопрос. А почему?
>
> Потому что русский язык велик и могуч. И читать на нём надо
> не по диагонали. Ответ у тебя прямо перед носом:
>
> > Инициализатор из любого промежуточного состояния -- это
>
> > не конструктор, это совсем другой метод, возможно, что
> с
> > совершенно иной логикой работы.
>
> Sapienti sat.


Я лишь прочитал, что написано. Не больше, не меньше.
По остальному Вы трактуете свои слова как хотите.

Я так понимаю здесь идет намек на разницу в С++ между конструктором копий и оператором =. (на смысл этой оптимизации, отсутствие финализации lvalue)

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


 
oxffff ©   (2011-01-13 12:47) [25]


> да, можно обойтись, код из Init передать в конструктор.
> И реинициализировать вызовом конструктора.
>
>
> constructor TFoo.Create;
> begin
> inherited;
> FListField := TList.Create;  
> ... <код, перенесённый из Init>
> end;
>
> И звиздец котёнку.


Заимствую упоминаемое ИШ выражение про стеклянный ....


 
Cobalt ©   (2011-01-13 12:49) [26]

2 oxffff ©   (13.01.11 12:00) [21]
В TStrings есть метод Create, а есть метод Clear

Используйте нужный


 
oxffff ©   (2011-01-13 12:51) [27]


> Cobalt ©   (13.01.11 12:49) [26]
> 2 oxffff ©   (13.01.11 12:00) [21]
> В TStrings есть метод Create, а есть метод Clear
>
> Используйте нужный


Я написал не про то, что так нужно делать всегда, а про то, когда create и init идентичен по семантике и необходимости виртуального конструктора.


 
Ega23 ©   (2011-01-13 12:57) [28]


> Я написал не про то, что так нужно делать всегда, а про
> то, когда create и init идентичен по семантике и необходимости
> виртуального конструктора.


Идентичен - да.
Хорошо, я по-другому переформулирую: ты сам бы написал такой код в коммерческом проекте?


 
oxffff ©   (2011-01-13 14:13) [29]


> Ega23 ©   (13.01.11 12:57) [28]
>
> > Я написал не про то, что так нужно делать всегда, а про
>
> > то, когда create и init идентичен по семантике и необходимости
>
> > виртуального конструктора.
>
>
> Идентичен - да.
> Хорошо, я по-другому переформулирую: ты сам бы написал такой
> код в коммерческом проекте?


Я бы не стал писать так. Однако ничего плохого не вижу в этом стиле.


 
oxffff ©   (2011-01-13 14:13) [30]


> Однако ничего плохого не вижу в этом стиле.


Точнее страшного.


 
Ega23 ©   (2011-01-13 14:16) [31]


> Я бы не стал писать так. Однако ничего плохого не вижу в
> этом стиле.


Собственно, этим всё сказано.
Я бы тоже не стал. Именно по причине невозможности нормального масштабирования дерева классов.


 
Cobalt ©   (2011-01-13 15:24) [32]

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


 
oxffff ©   (2011-01-13 16:03) [33]


> Cobalt ©   (13.01.11 15:24) [32]
> Нет ничего плохого в том, чтобы забивать гвозди микроскопом
> :)
> Задача выполнена? Выполнена.
> Просто это выглядит странно.


Забивать нужно с умом.
Если два метода семантически эквивалентны, то зачем спрашивается их два, а не один?


 
DiamondShark ©   (2011-01-13 17:00) [34]


> Если два метода семантически эквивалентны

Они семантически не эквивалентны.
Они реализуют разные ветки перехода на графе состояний объекта.


 
oxffff ©   (2011-01-13 17:20) [35]


> DiamondShark ©   (13.01.11 17:00) [34]
>
> > Если два метода семантически эквивалентны
>
> Они семантически не эквивалентны.
> Они реализуют разные ветки перехода на графе состояний объекта.
>


У кого как.


 
DiamondShark ©   (2011-01-13 18:59) [36]


> oxffff ©   (13.01.11 17:20) [35]
> У кого как.

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

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

Наконец, вызывает большое сомнения сама необходимость реинициализации. Нет сценариев, в которых реинициализация дала бы преимущество перед повторной инстанциацией.


 
_Юрий   (2011-01-13 20:12) [37]

а кто нибудь может формально доказать, почему при стиле программирования "состояние после инициализации не меняется никогда", количество ошибок в программе ощутимо снижается?


 
DiamondShark ©   (2011-01-13 20:25) [38]


> _Юрий   (13.01.11 20:12) [37]

Доказать такое формально нельзя.
Потому что понятие "ощутимо снижается" не имеет формального определения.

Но можно предположить, что ощутимо сужается пространство свободы для шаловливых ручонок.


 
Ega23 ©   (2011-01-13 20:43) [39]


>  Нет сценариев, в которых реинициализация дала бы преимущество
> перед повторной инстанциацией.


Полно. Сам недавно такую схему реализовывал.


 
DiamondShark ©   (2011-01-13 20:51) [40]


> Ega23 ©   (13.01.11 20:43) [39]
> Полно.

Три примера найдёшь?


> Сам недавно такую схему реализовывал.

Давай посмотрим.


 
Leonid Troyanovsky ©   (2011-01-13 22:31) [41]


> Ega23 ©   (13.01.11 00:14) [8]

> Во всех остальных случаях точно также статичный метод через
> inherited можно вызвать.

Можно вызвать.
А зачем, если конструктор виртуальный.

> Тебя ведь не удивляет вызов

Меня уже давно никакой вызов не удивляет ;)

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2011-01-13 22:33) [42]


> KSergey ©   (13.01.11 09:27) [12]

> Потомки конкретного класса не будут конструироваться через
> фабрику. Никогда.

Ну, и хрен с ней, с фабрикой.

--
Regards, LVT.


 
oxffff ©   (2011-01-14 08:49) [43]


> DiamondShark ©   (13.01.11 18:59) [36]
>
> > oxffff ©   (13.01.11 17:20) [35]
> > У кого как.
>
> Ни у кого ни как.
> По-определению, конструктор переводит объект из состояния
> "Выделен" в состояние "Инициализирован", а метод реинициализации
> переводит объект из любого промежуточного состояния в состояние
> "Инициализирован".
> Иными словами, конструктор реализует одну единственную дугу
> графа состояний, а метод реинициализации должен реализовывать
> потенциально бесконечное множество дуг графа состояний.
> Даже в предельно примитивном случае, когда объект, кроме
> терминальных состояний, имеет только одно рабочее состояние,
>  конструктор и реинициализатор реализуют разные дуги графа
> состояний. Даже если у тебя логика конструкции и реинициализации
> примитивны и вторая покравает первую, так, что тело конструктора
> сводится к единственному вызову реинициализатора, то это
> твой маленький секрет, деталь реализации, на которую клиент
> объекта ни в коем случае не имеет права полагаться.
>
> Возможность вызова конструктора как метода -- это именно
> багофича конкретной реализации языка, появившаяся ради неусложнения
> компилятора. Никогда конструктор не задумывался как реинициализатор.
>  Никакие объекты стандартной библиотеки не проектировались
> с возможностью использования конструктора как реинициализатора,
>  никогда такой сценарий не документировался. Никогда такой
> сценарий не должен использоваться в новом дизайне, потому
> что нарушает привычные паттерны сложившейся практики, требует
> особого документирования, и, кроме вырожденных случаев,
> не даёт никакой экономии.
>
> Наконец, вызывает большое сомнения сама необходимость реинициализации.
>  Нет сценариев, в которых реинициализация дала бы преимущество
> перед повторной инстанциацией.


У меня единственный вопрос? :)
Где можно ознакомиться с Вашими трудами в области конструкторов.
В других языках аллокатор указывается явно как new

Например help говорит, что обычно вызывается, но не говорит, что вызывать вне конструктора плохо.

When a constructor is called using an object reference (rather than a class reference), it does not create an object. Instead, the constructor operates on the specified object, executing only the statements in the constructor"s implementation, and then returns a reference to the object. A constructor is typically invoked on an object reference in conjunction with the reserved word inherited to execute an inherited constructor

Теперь по дугам графа

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


 
oxffff ©   (2011-01-14 09:31) [44]


> DiamondShark ©   (13.01.11 18:59) [36]
>
> > oxffff ©   (13.01.11 17:20) [35]
> > У кого как.
>
> Наконец, вызывает большое сомнения сама необходимость реинициализации.
>  Нет сценариев, в которых реинициализация дала бы преимущество
> перед повторной инстанциацией.


Если память выделяется в куче и освобождается из нее.
То завтраты на аллокацию нового и деаллокацию старого станут ощутимыми при большом количестве таких операций.


 
DiamondShark ©   (2011-01-14 10:12) [45]


> oxffff ©   (14.01.11 08:49) [43]
> У меня единственный вопрос? :)Где можно ознакомиться с Вашими
> трудами в области конструкторов.

"Сперва добейся" детектед.
У меня единственный ответ: фсад.
Дискуссия закончена.


 
KSergey ©   (2011-01-14 15:27) [46]

oxffff ©   (14.01.11 08:49) [43]
> Было бы убудительно привести конктретный пример, где это
> конкретно может ударить по пальцам и что нельзя написать
> по другому и писать нужно именно как

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

Вот передо мной проект на дельфи. Сичтаим, что дельфи я знаю более-менее, и понимаю что и как пихать в конструкторы/деструкторы и как их вызывать по задумке создателя.
При добавлении функциональности понадобился внутри объекта вложенный объект. Вещь вполне нормальная и естественная.
Добавляю в конструктор объекта строчку, которая по определению только в конструкторе и должна жить:

list := TList.Create;

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

Вы извините за эпитеты, но если вы не видите ничего страшного в применении такого подхода в коммерческом ПО....


 
Ega23 ©   (2011-01-14 15:40) [47]


> Давай посмотрим.


Объект с выделенным буфером внутри.
Clear перекидывает позицию "курсора"  в ноль.
Destroy - вызывает FreeMem.
Выделение памяти - однократное, использование - многократное.


 
oxffff ©   (2011-01-14 15:59) [48]


> KSergey ©   (14.01.11 15:27) [46]
> oxffff ©   (14.01.11 08:49) [43]
> > Было бы убудительно привести конктретный пример, где это
>
> > конкретно может ударить по пальцам и что нельзя написать
>
> > по другому и писать нужно именно как
>
> Элементарно.
>
> Вот передо мной проект на дельфи. Сичтаим, что дельфи я
> знаю более-менее, и понимаю что и как пихать в конструкторы/деструкторы

> и как их вызывать по задумке создателя.
> При добавлении функциональности понадобился внутри объекта
> вложенный объект. Вещь вполне нормальная и естественная.
>
> Добавляю в конструктор объекта строчку, которая по определению
> только в конструкторе и должна жить:
>
> list := TList.Create;
>
> И вдруг выясняется, что дебил (хорошо, пусть будет умник)
> коллега/предшественник решил, что конструкторы можно вызывать
> где и когда угодно лишь потому, что они, видите ли, "семантически
> идентичны инициализации".
>
> Вы извините за эпитеты, но если вы не видите ничего страшного
> в применении такого подхода в коммерческом ПО....


Видимо знаете Delphi не настолько хорошо.
Читайте про NewInstance.


 
oxffff ©   (2011-01-14 16:07) [49]


> KSergey ©   (14.01.11 15:27) [46]
> oxffff ©   (14.01.11 08:49) [43]
>
> list := TList.Create;


Существует по крайней мере еще 3 варианта решения этого вопроса.

1. Список создается по требованию.
2. if assigned(List) then List.clear else List:=TList.Create;
3. Проверка регистра dl.

Однако newinstance самый безболезненный.


 
Ega23 ©   (2011-01-14 16:14) [50]


> oxffff ©   (14.01.11 16:07) [49]


Серёж, академические рассуждения о сферических конях в вакууме - это прекрасно!
Но ты же сам сказал, что не стал бы такое в коммерческом коде использовать.
Собственно, на этом вопрос можно закрыть, либо в потрепаловку перенести, так сказать, "о высоких материях".


 
oxffff ©   (2011-01-14 16:24) [51]


> Ega23 ©   (14.01.11 16:14) [50]


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

Подобравшись вплотную к первой версии YAR(в которой есть записи с instance и static методами, но нет ООП), начинаешь задуматься о решениях других людей в рамках ООП и причинах таких решений и их последствиях.


 
oxffff ©   (2011-01-14 16:28) [52]


> Ega23 ©   (14.01.11 16:14) [50]
>
> > oxffff ©   (14.01.11 16:07) [49]
>
>
> Серёж, академические рассуждения о сферических конях в вакууме
> - это прекрасно!
> Но ты же сам сказал, что не стал бы такое в коммерческом
> коде использовать.


Наоборот чем сложнее и качественнее ты напишешь, тем больше завязан на тебе шеф и работодатель. :)


 
Ega23 ©   (2011-01-14 16:30) [53]


> Наоборот чем сложнее и качественнее ты напишешь, тем больше
> завязан на тебе шеф и работодатель. :)

Ну тогда вызвать в деструкторе конструктор для реинициализации. :)


 
oxffff ©   (2011-01-14 16:33) [54]


> Ega23 ©   (14.01.11 16:30) [53]
>
> > Наоборот чем сложнее и качественнее ты напишешь, тем больше
>
> > завязан на тебе шеф и работодатель. :)
>
> Ну тогда вызвать в деструкторе конструктор для реинициализации.
>  :)


На воскрешение намекаешь. :)


 
KSergey ©   (2011-01-14 20:08) [55]

> 2. if assigned(List) then List.clear else List:=TList.Create;

При каждом обращении тоже вставлять такую ахинею....

Извините за переход на личности, но эти люди еще носят синие штаны...
Не, я бы понял, если бы все эти рассуждения были сказаны "для примера", "вот так вот еще можно сделать", дабы блеснуть (в хорошем смысле) глубиной и широтой познаний.
Но настаивать на этом?!


 
Ins ©   (2011-01-14 20:49) [56]


> Leonid Troyanovsky ©   (12.01.11 22:13) [7]


В TObject, видимо, о потомках не подумали ))))


 
oxffff ©   (2011-01-14 21:25) [57]


> KSergey ©   (14.01.11 20:08) [55]
> > 2. if assigned(List) then List.clear else List:=TList.
> Create;
>
> При каждом обращении тоже вставлять такую ахинею....
>
> Не, я бы понял, если бы все эти рассуждения были сказаны
> "для примера", "вот так вот еще можно сделать", дабы блеснуть
> (в хорошем смысле) глубиной и широтой познаний.
> Но настаивать на этом?!


Пример N 1:

 TMytype=class
 constructor create;virtual;abstract;
 end;

 TMytypeChild=class(TMytype)
 protected
 List:TList;
 class function NewInstance: TObject;override;
 constructor create;override;
 destructor destroy;override;
 end;

{ TMytypeChild }

constructor TMytypeChild.create;
begin
inherited;
List.Clear;
end;

destructor TMytypeChild.destroy;
begin
List.free;
inherited;
end;

class function TMytypeChild.NewInstance: TObject;
begin
result:=inherited NewInstance;
with TMytypeChild(result) do
begin
List:=TList.create;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var Mytype:TMytype;
begin
Mytype:=TMytypeChild.create;
Mytype.create;
Mytype.free;
end;


 
oxffff ©   (2011-01-14 21:28) [58]


> KSergey ©   (14.01.11 20:08) [55]
> > 2. if assigned(List) then List.clear else List:=TList.
> Create;
>
> При каждом обращении тоже вставлять такую ахинею....


N 2

 TMytype=class
 constructor create;virtual;abstract;
 end;

 TMytypeChild=class(TMytype)
 protected
 List:TList;
 constructor create;override;
 destructor destroy;override;
 end;

constructor TMytypeChild.create;
begin
inherited;
if assigned(List) then list.Clear else List:=TList.create;
end;

destructor TMytypeChild.destroy;
begin
List.free;
inherited;
end;

procedure TForm1.Button1Click(Sender: TObject);
var Mytype:TMytype;
begin
Mytype:=TMytypeChild.create;
Mytype.create;
Mytype.free;
end;


 
oxffff ©   (2011-01-14 21:32) [59]

N 3

 TMytype=class
 constructor create;virtual;abstract;
 end;

 TMytypeChild=class(TMytype)
 protected
 lList:TList;
 public
 constructor create;override;
 destructor destroy;override;
 function GetList:TList;
 end;

constructor TMytypeChild.create;
begin
inherited;
if assigned(lList) then llist.Clear;
end;

destructor TMytypeChild.destroy;
begin
lList.free;
inherited;
end;

procedure TForm1.Button1Click(Sender: TObject);
var Mytype:TMytype;
begin
Mytype:=TMytypeChild.create;
Mytype.create;
Mytype.free;
end;

function TMytypeChild.GetList: TList;
begin
if not assigned(lList) then lList:=TList.create;
result:=lList;
end;


 
KSergey ©   (2011-01-14 21:33) [60]

> constructor TMytypeChild.create;
> begin
> inherited;
> if assigned(List) then list.Clear else List:=TList.create;
> end;

Вы можете объяснить ценность этой ахинеи?
То, что она работоспособна - спору нет.
но зачем это?!


 
oxffff ©   (2011-01-14 21:41) [61]


> KSergey ©   (14.01.11 21:33) [60]
> > constructor TMytypeChild.create;
> > begin
> > inherited;
> > if assigned(List) then list.Clear else List:=TList.create;
>
> > end;
>
> Вы можете объяснить ценность этой ахинеи?
> То, что она работоспособна - спору нет.
> но зачем это?!


Вокруг шум. Пусть так. Ни кипишуй. Всё ништяк.


 
oxffff ©   (2011-01-14 21:50) [62]


> KSergey ©   (14.01.11 21:33) [60]
> > constructor TMytypeChild.create;
> > begin
> > inherited;
> > if assigned(List) then list.Clear else List:=TList.create;
>
> > end;
>
> Вы можете объяснить ценность этой ахинеи?
> То, что она работоспособна - спору нет.
> но зачем это?!


type

TMytype=class
constructor create;virtual;abstract;
end;

TMytypeChild=class(TMytype)
protected
List:TList;
constructor create;override;
destructor destroy;override;
end;

TMytypeChildFull=class(TMytype)
protected
List:TList;
constructor create;override;
destructor destroy;override;
end;

constructor TMytypeChild.create;
begin
inherited;
if assigned(List) then list.Clear else List:=TList.create;
end;

{ TMytypeChildFull }

constructor TMytypeChildFull.create;
begin
inherited;
List:=TList.create;
end;

destructor TMytypeChildFull.destroy;
begin
List.free;
inherited;
end;

destructor TMytypeChild.destroy;
begin
List.free;
inherited;
end;

procedure TForm1.Button1Click(Sender: TObject);
var Mytype:TMytype;
   i:integer;
   D,W:DWORD;
begin
D:=GetTickCount;
Mytype:=TMytypeChild.create;
for i:=0 to 1000000 do
 begin
 Mytype.create;
 end;
Mytype.free;
D:=GetTickCount-D;

W:=GetTickCount;
for i:=0 to 1000000 do
 begin
 Mytype:=TMytypeChildFull.create;
 Mytype.free;
 end;
W:=GetTickCount-W;
showmessage("D="+inttostr(D)+" W="+inttostr(W));
end;

31 vs 359.


 
DiamondShark ©   (2011-01-14 21:51) [63]

Удалено модератором


 
_Юрий   (2011-01-14 21:53) [64]

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

Надо будет написать предложение в Эмберкадэро, пусть расширят синтаксис


 
oxffff ©   (2011-01-14 21:54) [65]


> DiamondShark ©   (14.01.11 21:51) [63]


А ты куда то слился когда тебе начинали приводить доводы с пользу реинициализация против повторного инстанцирования?


 
Игорь Шевченко ©   (2011-01-14 21:56) [66]

oxffff ©   (14.01.11 21:50) [62]

когда коту нечего делать...

Как же задолбали теоретики, кто б знал.


 
DiamondShark ©   (2011-01-14 21:57) [67]


> _Юрий   (14.01.11 21:53) [64]

Жжошь.

В новой версии YAR будет.


 
oxffff ©   (2011-01-14 21:57) [68]


> _Юрий   (14.01.11 21:53) [64]
> А если пойти дальше, то можно предположить, что неплохо
> бы иметь возможность вызова и деструктора не как деструктора,
>  а как просто метода, без разрушения экземпляра. Может быть,
>  кто-то хочет просто сбросить инициализацию.
>
> Надо будет написать предложение в Эмберкадэро, пусть расширят
> синтаксис


Если это нужно, то это можно сделать и сейчас по аналогии с .NET IDisposable с SuppressFinalize. Перекрыть FreeInstance и проверять флажок.
Повторяю, если это кому-либо пригодится.


 
oxffff ©   (2011-01-14 22:01) [69]


> Игорь Шевченко ©   (14.01.11 21:56) [66]
> oxffff ©   (14.01.11 21:50) [62]
>
> когда коту нечего делать...
>
> Как же задолбали теоретики, кто б знал.


Помнится давным давно мы с Вами обсуждали class helpers и вы выступали против них. Но прошло 2-3 года и вы их оценили.
Может каждому овощу свое время и место?


 
DiamondShark ©   (2011-01-14 22:02) [70]


> oxffff ©   (14.01.11 21:54) [65]

Мне обещали "да полно". Я попросил три (это же намного меньше, чем "да полно"). Дали один.
Я считаю, что вопрос исчерпан без комментариев.

А ты чего хотел? Польку-бабочку?


 
oxffff ©   (2011-01-14 22:08) [71]


> DiamondShark ©   (14.01.11 22:02) [70]
>
> > oxffff ©   (14.01.11 21:54) [65]
>
> Мне обещали "да полно". Я попросил три (это же намного меньше,
>  чем "да полно"). Дали один.
> Я считаю, что вопрос исчерпан без комментариев.
>
> А ты чего хотел? Польку-бабочку?


:) Да ничего я не хотел. Думал нормально обсудить по человечески.
А тут сразу. Да ты что навязывать собираешься и т.д.
Я же сразу привел пример с конструктором копий и оператором = и разницей между ними.
Просто привел сокращенный пример полезности виртуальности конструктора без введения дополнительного метода.
Делов то. А обвинили во всех смертных грехах.


 
oxffff ©   (2011-01-14 22:14) [72]

Даже в hepl"e написано хотите скорости аллокации и деаллокации делайте пул объектов и перекрывайте NewInstance и FreeInstance.
Кто-нибудь оценил? :)


 
KSergey ©   (2011-01-14 22:17) [73]

oxffff ©   (14.01.11 21:50) [62]
> 31 vs 359.

Ну сравнили несравнимое, и что?
Речь о другом: зачем на конструктор навешивать совершенно неожиданную функциональность?
Если внутри цикла нужна просто переинициализация (очистка) обхекта - ну так и вызвать метод Clear, что всем будет очевидно.
В чем ценность делать это вызовом метода с именем Create? вот что хочется узнать.

Это улучшит читабельность кода? это облегчит его сопровождение? что данный код изменит в мире к лучшему?


 
Игорь Шевченко ©   (2011-01-14 22:20) [74]

oxffff ©   (14.01.11 22:01) [69]


> Помнится давным давно мы с Вами обсуждали class helpers
> и вы выступали против них


Я выступаю не против class helpers, я выступаю за принцип - делай проще.


 
_Юрий   (2011-01-14 22:58) [75]


> oxffff ©   (14.01.11 22:14) [72]


> Кто-нибудь оценил? :)
>


Оценил. Геморрой, а сколько нибудь существенного выигрыша в скорости нету.
По приведенному коду:
это ни что иное, как способы выстрелить себе в ногу. Причем кнопка, запускаюшая пулю, называется "зарядить ружье"


 
Leonid Troyanovsky ©   (2011-01-14 23:00) [76]


> _Юрий   (14.01.11 21:53) [64]

> бы иметь возможность вызова и деструктора не как деструктора,
>  а как просто метода, без разрушения экземпляра. Может быть,
>  кто-то хочет просто сбросить инициализацию.

Трехмерные случайные блуждания невозвратны.

--
Regards, LVT.


 
oxffff ©   (2011-01-15 09:38) [77]


> KSergey ©   (14.01.11 22:17) [73]
> oxffff ©   (14.01.11 21:50) [62]
> > 31 vs 359.
>
> Ну сравнили несравнимое, и что?
> Речь о другом: зачем на конструктор навешивать совершенно
> неожиданную функциональность?
> Если внутри цикла нужна просто переинициализация (очистка)
> обхекта - ну так и вызвать метод Clear, что всем будет очевидно.
>
> В чем ценность делать это вызовом метода с именем Create?
>  вот что хочется узнать.
>
> Это улучшит читабельность кода? это облегчит его сопровождение?
>  что данный код изменит в мире к лучшему?


Да ничего не изменит. Тренируй свой мозг.


 
oxffff ©   (2011-01-15 09:39) [78]


> _Юрий   (14.01.11 22:58) [75]
>
> > oxffff ©   (14.01.11 22:14) [72]
>
>
> > Кто-нибудь оценил? :)
> >
>
>
> Оценил. Геморрой, а сколько нибудь существенного выигрыша
> в скорости нету.


Без комментариев.


 
oxffff ©   (2011-01-15 09:41) [79]


> В чем ценность делать это вызовом метода с именем Create?
>  вот что хочется узнать.


Если сложно абстрагироваться от конструктора и реинициализатора я ничем помочь не смогу.



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2011.04.10;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.71 MB
Время: 0.006 c
15-1292936633
>|
2010-12-21 16:03
2011.04.10
IN SOVIET RUSSIA ALL BEARS CAN DRIVE CARS&amp;#65279;


15-1293519707
12
2010-12-28 10:01
2011.04.10
Уходя от DBAware, зашился. Что можно мне посоветовать?


2-1294612841
Германн
2011-01-10 01:40
2011.04.10
Свойство RowSelect у компонента TTreeView


2-1294899349
12
2011-01-13 09:15
2011.04.10
Control.Enable := False Но, чтоб визуально не изменился.


15-1293022442
12
2010-12-22 15:54
2011.04.10
Черная дыра. Как она может быть такой, как пишут?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский