Основы программирования — второй семестр 08-09; Михалкович С.С.; IIа часть

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск

Введение в классы

Отличие классов от записей

Рассмотрим запись студент:

type
  Student = record
    name: string;
    age: integer;
    
    procedure Init(n: string; a: integer);
    begin
      name := n;
      age := a;
    end;
    
    procedure Print;
    begin
      writelnFormat('Имя: {0} Возраст: {1}',
                    name, age);
    end;
  end;

var
  s: student;
begin
  s.Init('Иванов', 18);
end.

Когда мы описываем переменную типа Student, соответствующая ей ячейка памяти отводится на программном стеке.

А вот так выглядит класс Student:

type
  Student = class
    name: string;
    age: integer;
    
    constructor Create(n: string; a: integer);
    begin
      name := n;
      age := a;
    end;
    
    procedure Print;
    begin
      writelnFormat('Имя: {0} Возраст: {1}',
                    name, age);
    end;
  end;

var
  s: Student;
begin
  s := new Student('Иванов', 18);
  s.Print;
end.

Переменная типа класс хранит ссылку на объект, память под который выделяется динамически при вызове конструктора. В памяти ссылка представляется как указатель - хранит адрес объекта. Однако, такой "указатель" как бы всегда разыменован (не надо писать s^). Если переменная типа класс представляет собой ссылку. то говорят. что в языке программирования реализована ссылочная объектная модель. В большинстве современных универсальных ЯП реализована именно ссылочная объектная модель (C#, Java, Delphi). Исключение составляет C++, в котором реализована размерная объектная модель.

является указателем. Для выделения динамической памяти под объект класса Student используется вызов специального метода, называемого конструктором (New Student(<имя>, <возраст>)).

Переменная Self

Внутри каждого нестатического метода имеется переменная Self, принадлежащая к типу данного класса и являющаяся ссылкой «на себя», т.е. на объект класса, вызывающий этот метод.

Поэтому возможно написать, например, так:

type
/// Студент
  Student = class
    /// Имя
    Name: string;
    /// Возраст
    Age: integer;
    /// Курс
    Course: integer;
    /// Группа
    Group: integer;

    constructor (Name: string; Age, Course, Group: integer);
    begin
      Self.Name := Name;
      Self.Age := Age;
      Self.Course := Course;
      Self.Group := Group;
    end;
  end;

Оказывается, во-первых, компилятор добавляет переменную Self в качестве первого параметра любого нестатического метода.
Во-вторых, при обращении к любому полю класса внутри метода, перед этим полем неявно добавляется Self.

Лекция 4

Шаблоны классов

type
  Point<T> = class
    x, y: T;

    constructor(x, y: T);
    begin
      Self.x := x;
      Self.y := y;
    end;
  end;

begin
  var p1 : Point<real>;
  var p2 : Point<integer>;

  p1 := new Point<real>(2.3, 5.7);
  p2 := new Point<integer>(2, 7);
  
  p1.x := 2;
  p2.x := 1.5; // ошибка компиляции, т.к. 
               // тип поля x объекта класса Point<integer> (integer) 
               // не совместим по присваиваиванию с вещественным типом real
  
  //можем пользоваться автоопределением типов:
  var p3 := new Point<real>(3.14, 7.9);
end.

Тип Point<T> называют обобщенным типом.

Теперь рассмотрим присваивание объектов класса:

var p11 := new Point<real>(0, 1.5);
var p12 := new Point<real>(2.3, 5);

p11 := p12;  // происходит присваивание ссылок:
             // p11 теперь указывает на тот же объект, что и p12;
             // область памяти, на которую до этого указывал p11 более недоступна

var p2 := new Point<integer>(5, 7);
p11 := p2;   // ошибка
             // типы объектов не совпадают

При присваивании же друг другу записей, происходит копирование самих записей.

Сборка мусора

(Garbage collection)

Мусор — любые ненужные объекты.
Под ненужными понимаются объекты, которые занимают память, но недоступны в программе.

Сборка мусора — процесс освобождения памяти, занятой ненужными объектами.

Обычно, сборка мусора запускается при нехватке места в памяти. Это позволяет не заботиться об утечках памяти, т.к. все выделенное — освободится. (При этом, от всех остальных ошибок мы не застрахованы!!!)
Главный недостаток механизма сборки мусора — во время сборки выполнение программы приостанавливается.