Рассмотрим пример программы из раздела Классы в С++. Программа использует простейший класс, объект которого печатает сообщение. Заметьте, что раньше класс был объявлен в одном файле с главной функцией, но такой способ утилизации классов не эффективен, почему, было рассмотрено в разделе Классы в С++. Так вот, теперь объявление класса находится в файле message.h , а реализация методов класса определена в файле message.cpp, а classes.cpp — файл с main() функцией.
// интерфейс класса, файл: message.h
class CppStudio // имя класса
{
public: // спецификатор доступа
void message(); // функция (метод класса) выводящая сообщение на экран
}; // конец объявления класса CppStudio
В h-файл помещен только лишь интерфейс класса, далее h-файл будет модифицирован с целью предотвращения ошибки многократного включения заголовочных файлов.
// реализация класса CppStudio, файл: message.cpp
#include "stdafx.h"
// связываем интерфейс класса с его реализацией
#include "message.h"
// подключаем прототип оператора cout
#include <iostream>
void CppStudio::message() // функция (метод класса) выводящая сообщение на экран
{
std::cout << "website: cppstudio.com\ntheme: Classes and Objects in C + +\n";
}
Реализация данного класса включает в себя всего один метод, который печатает сообщение.
// classes.cpp: определяет точку входа для консольного приложения.
#include "stdafx.h"
#include <iostream>
using namespace std;
#include "message.h"
int main(int argc, char* argv[])
{
CppStudio objMessage; // объявление объекта
objMessage.message(); // вызов функции класса message
system("pause");
return 0;
}
// код Code::Blocks
// код Dev-C++
// classes.cpp: определяет точку входа для консольного приложения.
#include <iostream>
using namespace std;
#include "message.h"
int main(int argc, char* argv[])
{
CppStudio objMessage; // объявление объекта
objMessage.message(); // вызов функции класса message
return 0;
}
Структура данной программы совсем простая, чего не скажешь о программах с большим объёмом кода. В таких программах, как правило, код расположен не в одном файле. И подключение заголовочных файлов выполняется не обязательно в главном файле. Поэтому существует вероятность многократного включения в программу заголовочного файла, что в свою очередь приводит к ошибке компиляции. В случае с нашей программой, заголовочный файл подключен в главном файле в строке 7 и программа нормально работает без всяких ошибок. А если же заголовочный файл message.h, по ошибке, был подключён не только в главном файле программы, но, и ,например, в файле stdafx.h. В таком случае при компиляции программы появится следующая ошибка:
//Ошибка 1 error C2011: CppStudio: переопределение типа "class"
То есть, компилятор сообщает о многократном включении заголовочного файла с классом CppStudio. В таком случае придется потратить своё время и убрать лишнее включение в программу заголовочного файла. Чтобы не возникало такого рода ошибок, в С++ существует специальная структура кода, которую ещё называют препроцессорная обёртка.
// препроцессорная обёртка, файл: message.h с интерфейсом класса
#ifndef CPPSTUDIO_H // если имя CPPSTUDIO_H ещё не определено
#define CPPSTUDIO_H // определить имя CPPSTUDIO_H
// определить класс CPPSTUDIO_H
class CppStudio // имя класса
{
public: // спецификатор доступа
void message(); // функция (метод класса) выводящая сообщение на экран
}; // конец объявления класса CppStudio
#endif CPPSTUDIO_H // если имя CPPSTUDIO_H уже определено, повторно не определять
Данная препроцессорная обёртка предотвращает попытку многократного включения заголовочных файлов. Препроцессорные директивы обрабатываются до этапа компиляции, программой-препроцессором. Который, в свою очередь не допускает многократного определения одного и того же класса. Препроцессорная обёртка похожа на оператор условного выбора if. Директива #ifndef проверяет, определено ли имя CPPSTUDIO_H, если нет, то управление передаётся директиве #define и определяется интерфейс класса. Если же имя CPPSTUDIO_H уже определено, управление передаётся директиве #endif. Таким образом, исключается возможность многократного определения класса CPPSTUDIO_H.
Обратите внимание на то, как написано имя класса, используемое в сочетании с директивами препроцессорной обёртки — CPPSTUDIO_H. Берётся имя заголовочного файла, в котором объявлен класс, причём имя принято записывать буквами верхнего регистра, а вместо точки ставить символ нижнего подчёркивания. Конечно же, имя может быть любым другим, но оно должно быть одинаковым во всех трёх директивах. Итак, структура препроцессорной обёртки такова:
// структура препроцессорной обёртки #ifndef /*ИМЯ ЗАГОЛОВОЧНОГО ФАЙЛА_H*/ #define /*ИМЯ ЗАГОЛОВОЧНОГО ФАЙЛА_H*/ // определение класса #endif /*ИМЯ ЗАГОЛОВОЧНОГО ФАЙЛА_H*/
С использованием препроцессорной обёртки, попытки подключения одного и того же файла, ошибки переопределения не вызовут. Этот же приём применяется и для предотвращения многократного определения функций, только если функции вынесены в отдельный файл.
Комментарии
Vaidokcrunk
Заказать Сиалис в РФ
Даже если взрослый мужик придерживается здорового образа жизни, ежегодно проходит все обследования и бегает по утрам, рано или поздно его все-равно поджидают трудности с потенцией: такова неприятная суть старения.
К большому счастью современная медицина создала [url=http://via-sexgra.ru/levitra-kupit-moskva]дженерик левитра отзывы[/url] , которые смогут продлить здоровую интимную жизнь на полтора десятка лет, не причиняя вреда при этом здоровью всех других органов и систем. Речь идет о Виагре дженериках, что вы можете заказать на этом портале via-sexgra.ru
Тут вас ожидает каталог из нескольких десятков препаратов, которые десятки лет производятся в США и прошли все нужные процедуры клинических проверок. В отличии от простых аптек, в указанном онлайн магазине все препараты продаются по минимальным расценкам и высылаются клиенту в простой посылке, что обеспечивает конфиденциальность заказа.
Все распространяемые таблетки изготавливаются на легальных европейских фармацевтических конвейерах и сопровождаются всеми легализованными документами. А небольшая стоимость дженериков обусловлена отсутствием огромной цепи посредников, как в случае с обычной аптекой.
Denya Lorents
Возможно эту статью следует переставить на чуть более ранний этап обучения? Где-то ближе к вынесению функции в отдельный файл.
Илья Бологан
а не проще с помощью
eagle_vik
Илья, можно и
, но учти что это работает только на Windows-платформах! Если ты будешь кодить под Unix системы, то там эту директиву не распознает, и она просто работать не будет!