
- •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. Статические члены класса
3.6. Встроенные функции-члены
В каждом из примеров классов, приведенных в этой главе, функции-члены полностью определялись внутри тела определения класса. В качестве альтернативы можно объявить функцию-член внутри класса, а определить ее вне класса.
class CRectangle
{
private:
Int Left;
int Top;
Int Right;
Int Bottom;
public:
CRectangle ();
CRectangle {int L, int T, int R, int B);
void Draw (void);
void GetCoord (int *L, int *T, int *R, int *B);
void SetCoord (int L, int T, int R, int B};
};
При внешнем определении функции-члена перед ее именем нужно поставить имя класса с последующим оператором расширения области видимости «::».
#include <stdlib.h>
CRectangle::CRectangle ()
{
Left = Top = Right = Bottom = 0;
}
CRectangle::CRectangle (int L, int T, int R, int B)
{
SetCoord (L,T,R,B);
}
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::GetCoord (int *L, int *T, int *R, int *B)
{
*L = Left;
*T = Top;
*R = Right;
*B = Bottom;
}
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;
}
Есть существенное различие между функцией, определенной внутри тела класса, и функцией, определенной вне класса. По умолчанию для последней не выполняется inline-подстановка (см. описание inline-функций в гл. 2). Следовательно, очень короткие функции можно определить внутри тела класса, а более длинные – вне его. Например, конструкторы класса CRrectangle и метод GetCoord (самые короткие) могут быть определены внутри класса, а функции Draw и SetCoord (самые длинные) – вне его. Полное определение класса CRectangle приведено в листинге 3.1 в конце следующего раздела.
Можно заставить компилятор рассматривать функцию, заданную вне определения класса, как встроенную, используя спецификатор inline, как было описано в гл. 2. Например, можно сделать функцию CRectangle::GetCoord встроенной, объявив ее внутри определения класса CRectangle,
void inline GetCoord (int *L, int *T, int *R, int *B);
а затем определить ее вне описания класса.
void inline CRectangle::GetCoord (int *L, int *T, int *R, int *B)
{
*L = Left; *T = Top; *R = Right; *B = Bottom;
}
3.7. Организация исходных файлов
Если программа состоит из нескольких исходных файлов, написанных на языке C++, то определение класса обычно помещается вместе с определениями всех встроенных функций-членов внутри единого заголовочного файла (файла с расширением .h). Затем данный файл включается в любой исходный файл, в котором используется этот класс. Такая организация файлов гарантирует, что определение класса вместе с кодом любой встроенной функции будет доступно при обращении к классу или при вызовах его функций-членов. Как указывалось в гл. 2, компилятор должен иметь доступ к встроенной функции при каждом ее вызове.
Определения любых функций-членов, не являющихся встроенными, обычно также размещаются внутри отдельного файла, называемого файлом реализации класса. Скомпилированный вариант файла реализации необходимо скомпоновать с программой (например, путем включения файла реализации .срр в список файлов проекта Visual C++). Отметим: размещение определений не встроенных функций в файле заголовков вместо отдельного файла реализации приводит к ошибке компоновщика «повторное символическое определение» (symbol redefinition), если заголовочный файл включен более чем в один исходный файл.
Листинги 3.1 и 3.2 содержат полный исходный код последнего варианта класса CRectangle. Определение класса CRectangle помещено в файл с именем CRect.h (файл заголовков класса), а определения функций-членов, не являющихся встроенными, – в CRect.cpp (файл реализации класса).
Листинг 3.1
// CRect.h: файл заголовков CRectangle
class CRectangle
{
private: