Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.03.2010, 12:16   #1
AnTe
Форумчанин
 
Регистрация: 25.09.2008
Сообщений: 209
По умолчанию Что в ссылке на объект, после объявления?

Написал простенький пример.

Код:
  TObjMain = class
    Obj: TObjMain;
    function GoTest: string;
  end;
если взять var ObjMain: TObjMain;
потом создать ObjMain:= TObjMain.create;
то что будет лежать в ObjMain.Obj ?

тест объекта, на форме три лабела, ТЭдит, для вывода результатов, и кнопка стоп:

Код:
procedure TfmTest.btnGoClick(Sender: TObject);
var i: integer; ObjMain: TObjMain;
begin
  NotNil := 0;
  Errors := 0;
  IsAssigned := 0;
  Stopped := False;

  while not (Stopped) do
  begin
    if i mod 1000 = 555 then
    begin
      edti.Text := IntToStr(i);
      lblNotNil.Caption := IntToStr(NotNil);
      lblIsAssigned.Caption := IntToStr(IsAssigned);
      lblErrors.Caption := IntToStr(Errors);
      Application.ProcessMessages;
    end;

    ObjMain := TObjMain.Create;
    if ObjMain.Obj <> nil
      then
      inc(NotNil)
    else
      if Assigned(ObjMain.Obj)
        then
      begin
        inc(IsAssigned);
        try
          Showmessage(ObjMain.Obj.GoTest)
        except
          inc(Errors);
        end;
      end;
      ObjMain.Free;
    inc(i);
  end;
end;
работало довольно долго, 290766555 проходов - всегда в ObjMain.Obj лежит nil

Понимаю, что это не показатель, что делфя многое делает сама, но расслабляться нельзя. Может, где-нибудь появление nil-а сразу после объявления, документировано?

Ну некрасиво мне получится в каждом объекте писать присвоения nil куче его полей, а через одну строчку креатить их (такой у меня текст)
AnTe вне форума Ответить с цитированием
Старый 24.03.2010, 12:48   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Может, где-нибудь появление nil-а сразу после объявления, документировано?
Какого появления?
Ты создал обьект с пустыми полями, Конструктор сам по себе ничего не заполняет, это должен предусмотреть программист.
Вот зачем тебе ObjMain.Obj? Что ты дальше с ним делать будешь?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 24.03.2010, 13:16   #3
AnTe
Форумчанин
 
Регистрация: 25.09.2008
Сообщений: 209
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Какого появления?
Ты создал обьект с пустыми полями, Конструктор сам по себе ничего не заполняет, это должен предусмотреть программист.
да, но, судя по тесту в нём всегда nil ! хто его туда запысывал?

Цитата:
Сообщение от Stilet Посмотреть сообщение
Вот зачем тебе ObjMain.Obj? Что ты дальше с ним делать будешь?
Это тестовый пример, у меня структура классов. Если коротко - в конструкторе главного предка вызывается виртуальная процедура заполнения полей дефолтами. В этой процедуре заполняются все поля, из простых типов данных, и проверяется, если поля-объекты assigned, то вызывается их заполнение, иначе - ничего не делать, что мне и надо.

Поэтому конструкция:

Код:
procedure TcTemplateSpec.Create;
var i: integer;
begin
  inherited;

  gContent := TcGrid.Create;
  gContent_ := TcGrid.Create;
  gChanges := TcGrid.Create;
  gChanges_ := TcGrid.Create;
  gDenotation := TcGrid.Create;
  gAdditional := TcGrid.Create;
  gAdditional_ := TcGrid.Create;
...
end;
сработает только если после объявления в указателе nil (что пока и показывает практика). Если же нигде не регламентировано, что это должно быть всегда, придётся для каждого класса для подстраховки писать что-то подобное:


Код:
procedure TcTemplateSpec.Create;
var i: integer;
begin
  gContent := nil;
  gContent_ := nil;
  gChanges := nil;
  gChanges_ := nil;
  gDenotation := nil;
  gAdditional := nil;
  gAdditional_ := nil;

  inherited;

  gContent := TcGrid.Create;
  gContent_ := TcGrid.Create;
  gChanges := TcGrid.Create;
  gChanges_ := TcGrid.Create;
  gDenotation := TcGrid.Create;
  gAdditional := TcGrid.Create;
  gAdditional_ := TcGrid.Create;
...
end;
надо ли? что-то с ходу и не найду, где же почитать об этом..
AnTe вне форума Ответить с цитированием
Старый 24.03.2010, 13:24   #4
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Цитата:
Сообщение от AnTe Посмотреть сообщение
/// Может, где-нибудь появление nil-а сразу после объявления, документировано?
Конечно, документировано (Раздел Declaring Variables из справки):

If you don't explicitly initialize a global variable, the compiler initializes it to 0. Object instance data (fields) are also initialized to 0. On the Wiin32 platform, the contents of a local variable are undefined until a value is assigned to them. On the .NET platform, the CLR initializes all variables, including local variables, to 0.
alexBlack вне форума Ответить с цитированием
Старый 24.03.2010, 13:45   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
хто его туда запысывал?
Но ведь это удобно что nil
Если там будет черти-что то твоя программа может падать на ошибку, как это было со старыми ДОСовскими компиляторами, которые не инициализировали переменные.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 24.03.2010, 17:34   #6
AnTe
Форумчанин
 
Регистрация: 25.09.2008
Сообщений: 209
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Но ведь это удобно что nil
Если там будет черти-что то твоя программа может падать на ошибку, как это было со старыми ДОСовскими компиляторами, которые не инициализировали переменные.
конечно удобно! именно поэтому меня смущал совет:
Цитата:
Конструктор сам по себе ничего не заполняет, это должен предусмотреть программист.
мне то нужно, чтобы сразу было nil, т.е. это делал компилятор, я ведь задолбаюсь по десятку лишних нилов писать в каждом констукторе.


alexBlack, спасибо !!
но что-то я всё равно торможу, с переводом. Первая часть абзаца ясна:
If you don't explicitly initialize a global variable, the compiler initializes it to 0. Object instance data (fields) are also initialized to 0.
написано, что поля инициализируются в 0

а вторая часть:
On the Wiin32 platform, the contents of a local variable are undefined until a value is assigned to them.
относится только к локальным переменным (неопределённые значения), т.е. это не мой случай?
AnTe вне форума Ответить с цитированием
Старый 24.03.2010, 20:32   #7
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

"На платформе Win32 содержимое локальных переменных неопределено пока им не присвоено значение"

Да, это не Ваш случай.

Что касается объектов, если интересно, посмотрите реализацию TObject.NewInstance. (этот метод класса вызывается для выделения памяти при создании объекта).

Последний раз редактировалось alexBlack; 24.03.2010 в 20:41.
alexBlack вне форума Ответить с цитированием
Старый 26.03.2010, 04:30   #8
AnTe
Форумчанин
 
Регистрация: 25.09.2008
Сообщений: 209
По умолчанию

Да, действительно, всё там

а добавив в запрос гуглю "TObject.NewInstance" нашёл и статьи как раз по теме инициализации объекта, довольно интересно почитать. Вот одна из них:

http://www.delphikingdom.com/asp/vie...?catalogid=216

Ещё раз спасибо!
AnTe вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
В экземпляре объекта не задана ссылка на объект. Что не так? oleeg Общие вопросы .NET 0 08.03.2010 20:23
[C++] Инициализация массива структур отдельно от объявления MariyaL Помощь студентам 0 30.09.2009 12:27
Что означает override, идущий после функции? TwiX Общие вопросы Delphi 22 09.08.2009 18:31
Пробема объявления массива в заголовке процедуры. mmx358 Паскаль, Turbo Pascal, PascalABC.NET 16 29.06.2009 09:46
Вопрос по поводу объявления класса в С++ Билдер prikolist Общие вопросы C/C++ 2 08.04.2009 23:07