54_______________________________________________Глава 1

Lab = Labell;

Тогда указатель Lab становится как бы псевдонимом объекта Labell. Оба ука-
зателя: и Lab, и Labell ссылаются на один и тот же объект. Например, La-
bell->Caption и Lab->Caption ссылаются на надпись одной и той же метки.

В качестве типа объекта, на который ссылается указатель, можно задать void.
Например:

void *Lab;

Такой указатель на void можно рассматривать как указатель на объект любого
типа. В дальнейшем этому указателю можно задать простым присваиванием ссыл-
ку на объект любого типа. Но разыменование такого указателя требует примене-
ния явного приведения типов, поскольку компилятор не знает, на объект какого
типа в действительности ссылается указатель. Поэтому для него нельзя, напри-
мер, после присваивания ему ссылки на метку Labell (как в приведенном ранее
примере) написать просто Lab->Caption. Для ссылки на надпись Caption через
этот указатель надо писать ((TLabel *)Lab)->Caption, то есть явным образом при-
водить тип указателя Lab к типу «указатель на объект класса TLabel».

Можно создавать ссылку на объект с помощью указателя не на истинный
класс объекта, а на один из классов, которым наследует класс данного объекта.
Дело в том, что любой объект может рассматриваться не только как объект .своего
класса, но и как объект любого класса-предка. Это в общем достаточно естественно
для обычного понимания объектов в реальном мире. Так любой автомобиль может
рассматриваться не только как объект автомобилей данной марки, например,
«Жигули», но и как один из объектов более общих классов — автомобили, средст-
ва передвижения и т.д. Так же и объект в C++ может рассматриваться как объект
любого из классов предков.

Например, универсальным указателем на любой компонент может быть указа-
тель на класс TControI — базовый класс всех компонентов:

TControl *Contr;

Такому указателю можно непосредственно присваивать ссылку на любой ком-
понент. Например,

Contr = Labell;

При таком присваивании компилятор сам производит необходимое приведе-
ние типов.

Но с этим указателем Contr уже нельзя работать непосредственно как с указа-
телем на метку. Для него известны только свойства, объявленные в классе TCont-
rol. Это такие общие свойства всех компонентов, как, например, Name — имя. Не-
посредственная ссылка на специфические свойства классов — наследников невоз-
можна. Например, попытка написать код Contr->Caption вызовет сообщение ком-
пилятора об ошибке с текстом: « "Controls: '.TControl: :Caption' is not accessible. »,
смысл которого заключается в том, что свойство Caption в классе TControl недо-
ступно. Поэтому для доступа к методам и свойствам, отсутствующим в классе
TControl, надо осуществлять явное приведение типа указателя, например:

((TLabel *)Contr)->Caption

Этот код как бы говорит компилятору: «Рассматривай Contr как ссылку на
класс TLabel». И тогда никаких сообщений об ошибках не возникает.

Причина, по которой в ряде случаев для хранения ссылок на объекты исполь-
зуются указатели на объекты базовых классов, заключается в удобстве групповой
обработки объектов разных классов с помощью общих для них методов или для за-
дания значений общих для них свойств. Этот вопрос будет подробнее рассмотрен в
следующем разделе.

Выше рассматривалось присваивание указателю ссылки на уже существую-
щий объект. Но создание нового объекта тоже всегда связано с созданием указате-