
- •3.1. Определение класса
- •Int Left;
- •Int Right;
- •Int Bottom;
- •3.2. Создание экземпляра класса
- •Int Left;
- •Int Right;
- •Int Bottom;
- •3.3. Доступ к членам класса
- •Int Left;
- •Int Right;
- •Int Bottom;
- •3.4. Инкапсуляция
- •Int Left;
- •Int Right;
- •Int Bottom;
- •Int Left;
- •Int Right;
- •Int Bottom;
- •Int Left;
- •Int Right;
- •Int Bottom;
- •3.5. Конструкторы и деструкторы
- •3.5.1. Конструкторы
- •Int Left;
- •Int Right;
- •Int Bottom;
- •Int Left;
- •Int Right;
- •Int Bottom;
- •Int Left;
- •Int Right;
- •Int Bottom;
- •3.5.2. Деструкторы
- •3.5.3. Когда вызываются конструкторы и деструкторы
- •3.6. Встроенные функции-члены
- •Int Left;
- •Int Right;
- •Int Bottom;
- •3.7. Организация исходных файлов
- •Int Left;
- •Int Right;
- •Int Bottom;
- •3.8. Указатель this
- •3.9. Статические члены класса
Int Left;
int Top;
Int Right;
Int Bottom;
public:
CRectangle (}
{
Left = Top = Right = Bottom = 0;
}
CRectangle (int L, int T, int R, int B)
{
SetCoord (L, T, R, B);
}
void Draw (void);
void GetCoord (int *L, int *T, int *R, int *B)
{
*L - Left;
*T = Top;
*R = Right;
*В = Bottom;
}
void SetCoord (int L, int T, int R, int B);
};
Листинг 3.2
// CRect.cpp: файл реализации
#include "crect.h"
#include <stdlib.h>
void Line (int XI, int Yl, int X2, int Y2);
void CRectangle::Draw (void)
{
Line (Left, Top, Right, Top);
Line (Right, Top, Right, Bottom) ;
Line (Right, Bottom, Left, Bottom);
Line (Left, Bottom, Left, Top);
}
void CRectangle::SetCoord (int L, int T, int R, int B)
{
L = _min (_max (0,L), 80);
T = _min (_max (0,T), 25);
R = _min (_max (0,R), 80);
В = _min (_max (0,B), 25);
R = _max (R,L);
В = _max (B,T);
Left = L; Top = T; Right = R; Bottom = B;
}
При создании класса CRectangle предполагалось, что функция Line определена в другом модуле. Файл CRect.h должен быть включен в любой файл, содержащий ссылку на класс CRectangle (включая CRect.cpp!), а скомпилированный вариант CRect.cpp должен быть скомпонован с программой.
3.8. Указатель this
При ссылке на переменные-члены класса из кода, находящегося вне класса, в выражении всегда указывается экземпляр класса. Следовательно, компилятор может определить, какая копия переменных-членов ему доступна. Предположим, например, что класс CTest содержит переменную N, тогда в приведенном ниже коде сначала будет напечатана копия переменной N объекта Test1, а затем – объекта *PTest2.
CTest Testl;
CTest *PTest2 = new CTest;
//...
cout << Testl.N << '\n';
cout << Test2->N << '\n';
При ссылке на переменную-член внутри функции-члена частный экземпляр класса не описывается.
class CTest
{
public:
int N;
int GetN ()
{
return N; // N возвращается БЕЗ точного указания объекта
}
}
Как компилятор определяет, на какую копию переменной N ссылается метод класса? В действительности, компилятор передает методу класса скрытый указатель на объект. Функция использует именно этот скрытый указатель для доступа к корректной копии переменных-членов. Например, в вызове
Test.GetN ();
компилятор передает скрытый указатель GetN на объект Test. Функция GetN использует именно этот указатель для доступа к копии переменной N, принадлежащей объекту Test.
Можно непосредственно обратиться к скрытому указателю с использованием спецификатора this. Другими словами, внутри функции-члена this является предопределенным указателем, содержащим адрес объекта, на который ссылается функция (иногда называемого текущим объектом). Так функция GetN может быть описана следующим образом.
int GetN ()
{
return this->N; // эквивалентно 'return N;'
}
Имя функции-члена с выражением this-> перед ним является корректным, но не преследует ни какой цели, так как использование указателя this и так подразумевается в простой ссылке на переменную-член. Однако далее будет показано несколько практических применений указателя this.
Если нужно получить доступ к глобальным переменным или к функции, имеющей такое же имя, как переменная-член или функция-член, то перед именем необходимо поставить операцию расширения области видимости «::». Например:
int N = 0; // глобальная переменная N
class CTest
{
public:
int N; //переменная-член N
int Demo ()
{
cout << ::N << '\n'; // печать глобальной переменной N
cout << N << '\n'; // доступ к переменной-члену N
// с использованием указателя 'this'
}
}