Язык С++ для системного программирования. Имена-этикетки. Класс как область действия, страница 6

18.2 Использование указателей на функции-элементы (методы)

Синтаксис определения

тип_результата (имя_класса :: *имя_указателя)(параметры);

Чтобы использовать такой указатель, можно применить либо операцию .*указатель, либо à*указатель .

Пример

#include <stdio.h>
 
class A
 
{
 
public:
 
void f1( )
 
{
 
puts ("привет!");
 
}
 
void f2( )
 
{
 
puts ("пока!");
 
}
 
};
 
void main( )
 
{
 
void (A::pf)( )=&A::f1;
 
/*указателю pf на функции-элементы класса А присвоили
начальный адрес функции f1( )*/
 
Aq; //q - объект класса А
 
A*pA=&q;//указатель рА на класс А получил адрес объекта q
 
(q.*pf)( ); /равносильно вызову q.f1( );
 
pf=&A::f2; //Bpf занесен адрес функции f2( ).
 
(q.*pf)( ); //q.f2( );
 
(pAà*pf)( ); /*в указателе рА находится адрес объекта q. В указателе pf - адрес функции f2( ). Вызывается f2( ) с объектом q , т.е. q.f2( )*/
 
}

18.3 Указатель this

Обычная (нестатическая) функция - элемент класса, должна "знать" , с каким объектом класса она работает. При вызове такой функции в С++ передается скрытый параметр this. Это указатель, в котором находится начальный адрес объекта, вызвавшего функцию, или с которым работает эта функция. Обычно this используется для возврата результата работы функции по указателю (return this)или по ссылке (return *this) на подразумеваемый объект.

Конкретные примеры использования this будут приведены позже.

18.4 Специальные функции-элементы

Это некоторые функции - члены класса, от которых зависят способы создания, копирования, преобразования и уничтожения объектов класса. Часто эти функции создаются по умолчанию. Ниже будут рассмотрены некоторые специальные функции-члены:конструктор, конструктор копирования, операция присваивания, функции преобразования, деструктор.

18.4.1 Конструктор

Это функция - элемент с тем же именем, что и имя класса. Она вызывается компилятором всегда, когда создается объект класса. Конструктор ничего не возвращает. Поэтому для него не указывается тип результата. Он не наследуется, не может быть const, volatile, static, virtual.

Если конструктор явно не описан, то создается по умолчанию вида

имя_класса ( )

{

}

Это т.н. пустой конструктор.

Конструктор, как и другие функции, может быть перегружен. В частности, помимо пустого конструктора, вызываемого только при создании объекта, можно также определить конструктор, которыйпри создании объекта инициализирует его элементы - данные. Это можно сделать как в теле конструктора, так и с помощью списка инициализации элементов. Если есть константные (только для чтения) элементы - данные, то можно использовать только список инициализации.

Пример инициализации в теле конструктора

classcoord
 
{
 
float x, y;
 
public:
 
coord (float a, float b)
 
{
 
x=a;
 
y=b;
 
}
 
};
 
void main ( )
 
{
 
coordw (2.5, 12.3);
 
}

При создании объекта w класса coord будет вызван конструктор. Его формальные параметры а и b приобретут соответственно значения 2.5 и 12.3.

Выше уже было сказано, что константные элементы - данные можно инициализировать только с помощью списка инициализации. Этот список отделяется двоеточием (:) от заголовка определения конструктора и содержит элементы-данные (и базовые классы), разделенные запятыми.

Пример.

class coord
 
{
 
const float x,y;
 
public:
 
coord(float a, float b):x(a),y(b)
 
{
 
}
 
};
 
voidmain( )
 
{
 
coordw(2.5, 12.3);
 
}

Для неконстантных элементов-данных инициализацию можно призводить или в теле конструктора, или с помощью списка инициализации. Однако список инициализации является обязательным также, если элементом данных одного класса служит объект ранее описанного класса и конструктор этого (ранее описанного) класса реализует инициацию элементов данных любым из двух способов.