Присваивать этим полям значения можно достаточно легко, например так:
1
2
3
4
5
6
7
|
var Teacher1: TTeacher;
Student1: TStudent;
begin
Teacher1 := TTeacher.Create('Tyapkin Vladimir Alexeevich');
Student1 :- TStudent.Create('Pupkin Vasilyi Vasilievich');
Student1.MathTeacher := Teacher1;
end;
|
[important]При присвоении одному объекту А значения другого объекта B, для A присваивается лишьуказатель на объект B. Это означает, что и A и B будут ссылаться на один и тот же объект, на одну и ту же область оперативной памяти. Например, при изменении впоследствии объекта B (или А), изменится и значение, возвращаемое объектом А (или B), т.к. они являются одним и тем же объектом. Эта особенность очень широко используется, т.к. позволяет легко создавать различные взаимосвязи между классами. В данном случае все экземпляры классов можно считать указателями, если у одного объекта имеется несколько экземпляров, то они не копируют данные, они указывают на одни и те же данные.[/important]
Нельзя пройти мимо очень полезной функции Assigned, которая позволяет проверить, был ли присвоен какой-либо объект данному полю:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
var Teacher1: TTeacher;
Student1: TStudent;
begin
Teacher1 := TTeacher.Create('Tyapkin Vladimir Alexeevich');
Student1 :- TStudent.Create('Pupkin Vasilyi Vasilievich');
...
if not Assigned(Student1.MathTeacher) then
Student1.MathTeacher := Teacher1
else
ShowMessage('Студенту '+Student1.FullName + ' уже присвоен учитель математики '+Student1.MathTeacher);
end;
|
Ну и рассмотрим еще один несложный пример, в котором мы уже будем работать с целым массивом этих самых указателей на объекты. Для этого изучим класс TSchool. В нем описаны два массива: учителя и ученики. Заполнять их можно также просто:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
var i, n, j: integer;
school: TSchool;
begin
school := TSchool.Create(123);
n := 1;
for i := 1 to 10 do begin
school.Teachers[i] := TTeacher.Create('Teacher ' + IntToStr(i));
for j := 1 to 10 do begin
school.Students[n] := TStudent.Create('Student '+ IntToStr(n));
school.Students[n].MathTeacher := school.Teachers[i];
inc(n);
end;
end;
end;
|
В данном примере мы создаем 10 учителей и 100 учеников. Каждому ученику присваиваем в цикле учителя математики. Несложно заметить, что присвоение здесь выглядит также как и в случае с обыкновенными переменными, но нужно помнить, что присваиваются не значения самих объектов, а присваиваются указатели на объект.
Чтобы очистить поле или переменную-экземпляр, в котором ранее содержался объект, достаточно ему присвоить значение nil:
1
2
3
4
5
6
|
var school, schoollink: TSchool;
begin
school := TSchool.Create;
schoollink := school; // Создаем еще один указатель на объект
schoollink := nil; // Schoollink больше не является указателем на school
end;
|
[warning]Если вы обнулите (присвоите nil) всем указателем на один объект, то вы потеряете возможность обращаться к содержимому этого экземпляра. А как следствие это будет являться причиной утечки памяти, т.к. объект теперь никак не сможет быть освобожден, если ранее не был вызван деструктор.[/warning]
Ну и, конечно же, мы всегда можем обращаться к полям-объектам внутри методов текущего класса, а соответственно реализовывать необходимые аналогичные присвоения и многое другое.
|