Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по С++ глава 3.doc
Скачиваний:
13
Добавлен:
05.11.2018
Размер:
187.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: