Объект класса. Указатедь на объект класса

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
first-leon
новенький
Сообщения: 68
Зарегистрирован: 20.04.2006 18:46:31
Контактная информация:

Объект класса. Указатедь на объект класса

Сообщение first-leon »

Всем привет.
Пришел к такому умозаключанию: не имеет смысла создавать тип "указатель на объект", так как любая переменная типа "class" и есть указатель на объект. И если мы создаем тип "указатель на объект" то получаем указатель на указатель.

Код: Выделить всё

  Pa = ^Ta;
  a = class
    ..
  end;

Прав ли я?

P. S. Может это кажется тривиальным, но я все время делал тип "указателя на класс", и пользовался указателями на объект.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Совершенно верно. В этом состоит отличие современных типов "class" от считающихся устаревшими "object".
first-leon
новенький
Сообщения: 68
Зарегистрирован: 20.04.2006 18:46:31
Контактная информация:

Сообщение first-leon »

Ясно. Для себя сделал большое открытие. Но на самом деле код стал гораздо читабельнее (получалось по 2-3 крышки в одном выражении).
Maxizar
постоялец
Сообщения: 385
Зарегистрирован: 20.03.2010 18:48:14

Сообщение Maxizar »

Извините, что поднял такую старую тему, но хочется уяснить для себя раз и на всегда.
Я сам всегда делал так:

Код: Выделить всё

Type
          { TLayer1DPC }
     PLayer1DPC =^TLayer1DPC;
     TLayer1DPC = class   //Слой материала (кристалл) 
// -----
          PLayer :=New(PLayer1DPC);       //готовим новый указатель
          PLayer^:=TLayer1DPC.Create;    //Создаем класс на который указывает указатель

          Layers.Add(PLayer); //Запихиваем в листинг

Layers имеет тип TList;
И дальше пользовался.. когда надо было удалить память делал так:

Код: Выделить всё

procedure ClearLayerList;
var Index:Integer;
begin
     While Layers.Count>0 do
     begin
        Index:=Layers.Count-1;                   //Если удалять с конца так быстрее
        PLayer1DPC(Layers.Items[Index])^.Free;   //Уничтожение слоя как класс
        Dispose(PLayer1DPC(Layers.Items[Index]));//Освобождение памяти выделенной New
        Layers.Delete(Index);
     end;
end;

Это код работает на ура уже 3 года.

Но если при создании класса (вне зависимости от видимости переменной) он будет существовать до тех пор пока не будет вызван Free, то получается что действительно указатель на класс лишний, Для С\С++ получается указатель необходим, потому что при выходе из функции локальные переменные уничтожаются (для классов вызывается Free).
А указатель нет, будет существовать до тех пор пока не вызовем Dispose.
Я правильно понял?.

Согласно вот этому Reference guide for Free Pascal, version 2.2.4 (стр 64):
Manual писал(а):The extended syntax of new and dispose can not be used to instantiate and destroy class instances.
That construct is reserved for use with objects only. Calling the constructor will provoke a call to
getmem, to allocate enough space to hold the class instance data. After that, the constuctor’s code
is executed. The constructor has a pointer to its data, in Self.


Не может быть использован, но почему тогда мой код выше работал, и ни разу не подвел в течении 3 лет?.. может я не правильно перевл, если Да, тогда я вообще ничего не понимаю.
Т.е. код выше можно делать вообще так:

Код: Выделить всё

  Type
          { TLayer1DPC }
     PLayer1DPC =^TLayer1DPC;
     TLayer1DPC = class   //Слой материала (кристалл) 
// -----
          Layer:=TLayer1DPC.Create;    //Создаем класс на который указывает указатель

          Layers.Add(@Layer); //Запихиваем в листинг

И дальше пользовался.. когда надо было удалить память делал так:

Код: Выделить всё

procedure ClearLayerList;
var Index:Integer;
begin
     While Layers.Count>0 do
     begin
        Index:=Layers.Count-1;             
        TLayer1DPC(Layers.Items[Index]^).Free;   //Уничтожение слоя как класс
        Layers.Delete(Index);
     end;
end;


Это так?
Аватара пользователя
Иван Шихалев
энтузиаст
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург
Контактная информация:

Сообщение Иван Шихалев »

Maxizar писал(а):Это так?

Да, это так.

Старый код работал, потому что там не идет речи о манипулировании экземпляром класса через new/dispose, ими управляется указатель. А то, что он ссылается на тоже, по сути, указатель, ничего не меняет.
Maxizar
постоялец
Сообщения: 385
Зарегистрирован: 20.03.2010 18:48:14

Сообщение Maxizar »

Иван Шихалев - Спасибо, теперь все встало на свои места.
Ответить