Освой самостоятельно С++ за 21 день.
Шрифт:
Зачем же нужно отделять файл заголовка с расширением .hpp от файла программы с расширением cpp, если мы все равно собираемся вводить содержимое файла заголовка назад в файл программы? Как показывает практика, большую часть времени клиентов вашего класса не волнуют подробности его выполнения. При чтении небольшого файла заголовка они получают всю необходимую информацию и могут игнорировать файл с подробностями выполнения этого класса. Кроме того, не исключено, что содержимое файла заголовка с расширением .hpp вам захочется включить не в один, а
Примечание:Объявление класса сообщает компилятору, что представляет собой этот класс, какие данные он содержит и какими функциями располагает. Объявление класса называется его интерфейсом, поскольку оно сообщает пользователю, как взаимодействовать с классом. Интерфейс обычно хранится в файле с расширением .hpp, который называется файлом заголовка.
Из определения функции компилятор узнает, как она работает. Определение функции называется выполнением метода класса и хранится в файле с расширением .cpp. Подробности выполнения класса касаются только автора класса. Клиентам же класса, т.е. частям программы, использующим этот класс, не нужно знать, как выполняются функции.
Выполнение с подстановкой
Можно выполнять подстановку методов с помощью ключевого слова inline точно так же, как это делалось с обычными функциями. Для этого ключевое слово inline нужно разместить перед типом возвращаемого значения. Например, определение подставляемой функции-члена GetWeight имеет следующий вид:
inline intCat::GetWeight
{
return itsweight; // возвращает переменную-член Weight
}
Можно также поместить определение функции в объявление класса, что автоматически делает такую функцию подставляемой:
class Cat
{
public:
int GetWeight { return itsWeight; } // подставляемая функция
void SetWeight(int aWeight);
};
Обратите внимание на синтаксис определения функции GetWeight. Тело подставляемой функции начинается сразу же после объявления метода класса, причем после круглых скобок нет никакой точки с запятой. Подобно определению обычной функции, определение метода начинается с открывающей фигурной скобки и оканчивается закрывающей фигурной скобкой. Как обычно, пробелы значения не имеют, и то же самое определение можно записать несколько иначе:
class Cat
{
public:
int GetWeight const
{
return itsWeight;
} // подставляемая функция
void SetWeight(int aWeight);
};
В листингах 6.6 и 6.7 вновь создается класс Cat, но в данном случае объявление класса содержится в файле CAT.hpp, а выполнение — в файле CAT.cpp. Кроме того, в листинге 6.7 метод доступа к данным
Листинг 6.6. Объявление класса CAT в файле CAT.hpp
1: #include <iostream.h>
2: class Cat
3; {
4: public:
5: Cat (int initialAge);
6: ~Cat;
7: int GetAge const { return itsAge;) // подставляемая функция!
8: void SetAge (int age) { itsAge = age;} // подставляемая функция!
9: void Meow const { cout << "Мяу.\n";} // подставляемая функция!
10: private:
11: int itsAge;
12: };
Листинг 6.7. Выполнение масса Cat в файле CAT.cpp
1: // Пример использования подставляемых функций
2: // и включения файла заголовка
3:
4: #include "cat.hpp" // не забудьте включить файл заголовка!
5:
6:
7: Cat::Cat(int initialAge) //конструктор
8: {
9: itsAge = initialAge;
10: }
11:
12: Cat::~Cat // деструктор, не выполняет никаких действий
13: {
14: }
15:
16: // Создаем виртуальную кошку, устанавливаем ее возраст, разрешаем
17: // ей мяукнуть, сообщаем ее возраст, затем снова "мяукаем" и изменяем возраст кошки.
18: int main
19: {
20: Cat Frisky(5);
21: Frisky.Meow;
22: cout << "Frisky is а cat who is ";
23: cout << Frisky.QetAge << " years old.\n";
24: Frisky.Meow;
25: Frisky.SetAge(7);
26: cout << "Now Frisky is " ;
27: cout << Frisky.GetAge << " years old.\n";
28: return 0;
29: }
Результат:
Meow.
Frisky is а cat who is 5 years old.
Meow.
Now Frisky is 7 years old.
Анализ: Программа, представленная в листингах 6.6 и 6.7, аналогична программе из листинга 6.4 за исключением того, что три метода класса объявляются подставляемыми, а само объявление класса вынесено в файл заголовка CAT.hpp.
В строке 7 объявляется функция GetAge и тут же следует определение ее выполнения. Строки 8 и 9 занимают объявления еще двух встроенных функций, но их определения содержатся в другом файле.
В строке 4 листинга 6.7 с помощью команды #include "cat.hpp" в программу включается содержимое файла CAT.hpp. Компилятор получает команду считать содержимое файла cat .hpp и ввести его в данный файл, начиная со строки 5.
Возможность встраивания файлов в другие файлы позволяет хранить объявления классов отдельно от их выполнения и использовать тогда, когда в этом возникает необходимость. Это стандартный прием при создании программ на языке C++. Обычно объявления классов хранятся в файле с расширением .hpp, который затем включается в соответствующий файл .cpp с помощью директивы #include.