Типы данных

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

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

Re: Типы данных

Сообщение Ichthyander » 04.12.2017 18:38:33

Наверное проще будет понять, если выразиться кодом Pascal
Я о таких переменных класса TObject говорил
Код: Выделить всё
var
Obj: TObject; // Ну или любого другого класса наследника
begin
  Obj:=TObject.Create; // Понимаю, TObject - условно, имею ввиду любой наследник класса TObject
  Obj.Free; // Тут уничтожается объект. Притом в переменной остается указатель, но на объект он уже не указывает
  Obj:=nil; // Поэтому здесь мы можем присвоить переменной nil
end;

Вот о таких переменных типа TObject (и его наследников (то есть любых объектов)) я имел ввиду. Правильнее сказать может даже указатели на объекты класса TObject
Я понимаю, что есть еще переменные типа класса, то есть
Код: Выделить всё
var
  cls: TClass; // Замечу, что TClass является классом TObject, то есть TClass=class of TObject
begin
  cls:=obj.Classtype;
end;

О каком типе говорите Вы? Есть еще что-то помимо?
Аватара пользователя
Ichthyander
постоялец
 
Сообщения: 304
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Типы данных

Сообщение Лекс Айрин » 04.12.2017 18:44:31

Ichthyander писал(а):Есть еще что-то помимо?


Есть.

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

type
  PHelloWorld = ^THelloWorld;
  THelloWorld = object
    procedure Put;
  end;

var
  HelloWorld: PHelloWorld; { это указатель на THelloWorld }

procedure THelloWorld.Put;
begin
  WriteLn('Hello, World!');
end;

begin
   New(HelloWorld);
   HelloWorld^.Put;
   Dispose(HelloWorld);
end.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4169
Зарегистрирован: 19.02.2013 16:54:51

Re: Типы данных

Сообщение Дож » 04.12.2017 19:06:36

olegy123 писал(а):Еще вопрос возник к гуру - когда в функцию/процедуру передается ссылка а когда копия объекта и что возвращается . Существуют ли там подводные камни?

class-объекты всегда передаются как указатели.

Передача object'ов и record'ов определяется модификатором параметра (отсутствие модификатора означает передачу значения, var, out и constref передают переменную по ссылке, const определяется платформой и реализацией).

Я не знаю, зачем нужен был вообще тип TObject, но тому кто это придумал но путаницы это прибавило знатно.

Это один из способов упростить написание кода (классам не нужно объявлять P-тип, синтаксис вызова конструктора и деструктора проще, и вручную разыменовывать обращения к членам не требуется), не ломая при этом однозначность кода в старом стиле.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 689
Зарегистрирован: 12.10.2008 16:14:47

Re: Типы данных

Сообщение Лекс Айрин » 04.12.2017 19:12:21

Дож, я говорил конкретно о типе TObject. Тем более, что в программе он, в период перехода, был то объектом, то классом в зависимости от версии и инициировать его надо было по разному.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4169
Зарегистрирован: 19.02.2013 16:54:51

Re: Типы данных

Сообщение Ichthyander » 04.12.2017 19:24:15

Лекс Айрин писал(а):Есть.

Жесть!! :shock:
Куча вопросов сразу... То есть это действительно по сути record со счетчиков ссылок?
Аватара пользователя
Ichthyander
постоялец
 
Сообщения: 304
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Типы данных

Сообщение Лекс Айрин » 04.12.2017 19:34:40

Ichthyander писал(а):То есть это действительно по сути record со счетчиков ссылок?


По сути, да. Причем, я не уверен за счетчик ссылок. Есть, правда, еще и механизм инкапсуляции, который в начальном виде в объектах классического типа присутствовал (и присутствует) не полностью. Впрочем, полноценной инкапсуляции поддерживаемой языком нет до сих пор и в классах. И уже вряд ли будет, т. к. люди слишком привыкли лезть внутрь объекта, как в обычную запись. Хотя LCL построена, по возможности, как будто она есть.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4169
Зарегистрирован: 19.02.2013 16:54:51

Re: Типы данных

Сообщение Дож » 04.12.2017 19:41:21

У object'а, разумеется, нет никакого счётчика ссылок.

Дож, я говорил конкретно о типе TObject. Тем более, что в программе он, в период перехода, был то объектом, то классом в зависимости от версии и инициировать его надо было по разному.

Так-то он и сейчас "и объект, и класс": https://www.freepascal.org/docs-html/rt ... bject.html
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 689
Зарегистрирован: 12.10.2008 16:14:47

Re: Типы данных

Сообщение Ichthyander » 04.12.2017 19:49:58

Лекс Айрин писал(а):По сути, да. Причем, я не уверен за счетчик ссылок. Есть, правда, еще и механизм инкапсуляции, который в начальном виде в объектах классического типа присутствовал (и присутствует) не полностью. Впрочем, полноценной инкапсуляции поддерживаемой языком нет до сих пор и в классах. И уже вряд ли будет, т. к. люди слишком привыкли лезть внутрь объекта, как в обычную запись. Хотя LCL построена, по возможности, как будто она есть.
Я чувствую себя полным болваном...
Пока правда не знаю как это можно использовать и для чего )
Аватара пользователя
Ichthyander
постоялец
 
Сообщения: 304
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Типы данных

Сообщение Лекс Айрин » 04.12.2017 20:19:29

Ichthyander, ничего, постепенно пройдет. Лучше всего взять какой-нибудь более менее серьезный проект и попытаться его реализовать, постепенно накручивая его сложность. Примерно так все и поступают.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4169
Зарегистрирован: 19.02.2013 16:54:51

Re: Типы данных

Сообщение Ichthyander » 04.12.2017 20:25:13

Лекс Айрин писал(а):Ichthyander, ничего, постепенно пройдет. Лучше всего взять какой-нибудь более менее серьезный проект и попытаться его реализовать, постепенно накручивая его сложность. Примерно так все и поступают.

У меня есть проекты коммерческие и некоммерческие, не знаю, правда, что в Вашем понимании серьезный, и во всех я естественно использую ООП. Просто я не использовал объекты таким образом, как Вы указали и честно говоря не вижу необходимости.

Собственно, суть в том, что я работал с объектами через указатели, но не так как в том коде, где использовался New и Dispose для создании и удаления

Лекс Айрин и покажите мне пример "серьезного" проекта, где с объектами активно работают именно так. К примеру, из кода fpc или Lazarus
Аватара пользователя
Ichthyander
постоялец
 
Сообщения: 304
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Типы данных

Сообщение olegy123 » 04.12.2017 22:06:25

Дож писал(а):
olegy123 писал(а):Еще вопрос возник к гуру - когда в функцию/процедуру передается ссылка а когда копия объекта и что возвращается . Существуют ли там подводные камни?

class-объекты всегда передаются как указатели.

Передача object'ов и record'ов определяется модификатором параметра (отсутствие модификатора означает передачу значения, var, out и constref передают переменную по ссылке, const определяется платформой и реализацией).

Спасибо, разъяснили мне. То что мне надо.

Еще желательно узнать как функция возвращает данные..

допустим есть
Код: Выделить всё
function TestThreadSafety():TMatrix4x4d; // TMatrix4x4d:array [0..15] of Double - 16 элементов Double
begin
end;
Я так понимаю создается в стеке/куче Result:TMatrix4x4d ~ примерно Sizeof(16*8) элементов, которые потом копируются в m4x4(m4x4:=TestThreadSafety();)..
или же в теле TestThreadSafety() выделяется статично локально Result? типа
Код: Выделить всё
function TestThreadSafety():TMatrix4x4d; // TMatrix4x4d - 16 элементов Double
var
  Result:TMatrix4x4d;
begin
end;

- т.е. меня волнует потокобезопасен ли Result в функции?
т.е. Result одновременно для разных потоков будет разный? Или это будет один и тот же участок в памяти?
olegy123
энтузиаст
 
Сообщения: 757
Зарегистрирован: 25.02.2016 12:10:20

Re: Типы данных

Сообщение Mikhail » 04.12.2017 22:55:49

olegy123 писал(а):т.е. Result одновременно для разных потоков будет разный?


Смотря что слева стоит, если это временный объект или локальная переменная, то это будет стек.
Mikhail
постоялец
 
Сообщения: 479
Зарегистрирован: 24.10.2013 16:06:47

Re: Типы данных

Сообщение serbod » 04.12.2017 23:15:54

Тип object бывает очень полезен для короткоживущих объектов без четкого времени жизни, когда создается в одном месте, а освобождается неизвестно где, а так же как "record с методами". Итераторы, обертки над THandle, элементы массивов.

Вот пример итератора "из головы", должен работать на всех паскалях от Turbo Pascal до Delphi XE.

Код: Выделить всё
type TStringsIterator = object
private
  FNextIndex: Integer;
  FStrings: TStrings;
public
  constructor Init(AStrings: TStrings);
  function GetNext(out s: string): Boolean;
end;

constructor TStringsIterator.Init(AStrings: TStrings);
begin
  FStrings := AStrings;
  FNextIndex := 0;
end;

function TStringsIterator.GetNext(out s: string): Boolean;
begin
  Result := (FNextIndex < FStrings.Count);
  if Result then
  begin
    s := FStrings[FNextIndex];
    Inc(FNextIndex);
  end;
end;

// пример использования
var
  s: string;
  StringsIterator: TStringsIterator;
begin
  StringsIterator.Init(Memo1.Lines);
  while StringsIterator.GetNext(s) do
    WriteLn(s);
end;
Аватара пользователя
serbod
постоялец
 
Сообщения: 215
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Типы данных

Сообщение Mikhail » 04.12.2017 23:27:40

А вообще фееричный тред. :)

Напомню, object это старый тип, переменные этого типа могли располагаться как на стеке так и в куче. В отличие от крестов деструкторы там автоматически не вызывались (хотя память, выделенная на стеке, освобождается). Кстати, конструктор и деструктор были не обязательны, если не было виртуальных методов. Для создания объекта в куче использовался расширенный синтаксис new и dispose, примерно так
Код: Выделить всё
type PMyObject = ^TMyObject;
       TMyObject = object
       ...
       constructor Init;
       destructor Done;
       end;

var p: PMyObject;
...

//так
p:=new(PMyObject, Init);
//или так
new(p, Init);
//уничтожение
dispose(p, Done);


При обращении к элементам класса разыменовывание происходит автоматически (если стоит соответствующий ключ компилятора).Иначе надо писать, примерно так.
Код: Выделить всё
p^.MyMethod();


Этот тип не поддерживает интерфейсы и считается устаревшим, вместо него следует использовать class. Переменные этого типа, по сути, являются типизированными указателями, а сами объекты ВСЕГДА! располагаются в куче. Кроме того, вся иерархия объектов происходит от специального, встроенного класса TObject.
Обращаю внимание, все классы являются дочерними по отношению к встроенному в компилятор классу TObject.

Кроме этого, есть еще несколько типов, которые скрывают свою сущность указателя, кроме классов это некоторые строки, динамические массивы и интерфейсы. Они также автоматически разыменовываются и не только!

Добавлено спустя 6 минут 35 секунд:
Да и еще по поводу передачи параметров, для классов, динамических массивов, строк (не все), интерфейсов передаются ссылки. Для типов со счетчиком ссылок он может изменяться в зависимости от типа параметра. По поводу присваивания... вопрос сложный... обычно просто копируется ссылка, но иногда происходит копирование. :)
Mikhail
постоялец
 
Сообщения: 479
Зарегистрирован: 24.10.2013 16:06:47

Re: Типы данных

Сообщение serbod » 04.12.2017 23:59:59

Mikhail писал(а):Да и еще по поводу передачи параметров, для классов, динамических массивов, строк (не все), интерфейсов передаются ссылки. Для типов со счетчиком ссылок он может изменяться в зависимости от типа параметра. По поводу присваивания... вопрос сложный... обычно просто копируется ссылка, но иногда происходит копирование.


Для переменных со счетчиком ссылок (array, string, object) используется "copy-on-write", то есть копия значения переменной создается перед записью в переменную. Если в переменную ничего не писать, то она так и останется указателем. Но это может вызвать всякие нежелательные эффекты в многопоточных программах, поэтому при многопоточности лучше принудительно копировать значение при помощи Copy().
Аватара пользователя
serbod
постоялец
 
Сообщения: 215
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Пред.След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru