Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Содержание сайт... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Модуль Forms 62832
Создание отчето... 62825
ТЕХНОЛОГИИ ДОСТ... 59358
Пример работы с... 58083
Имитационное мо... 54756
Реклама
Сейчас на сайте
Гостей: 14
На сайте нет зарегистрированных пользователей

Пользователей: 13,073
новичок: DENIS1996
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Моделирование вычислительного центра на GPSS + Отчет + Блок схема
Компьютерный магазин на Turbo Pascal (База данных) + Пояснительная записка
Моделирование работы перекрёстка по регулированию движения на GPSS + Поя...

Реклама



Подписывайся на YouTube канал о программировании, что бы не пропустить новые видео!

ПОДПИСЫВАЙСЯ на канал о программировании
«Стражи» включения
Продолжая развитие нашего проекта со стеком, создадим третий модуль, в котором объект класса TStack будет передаваться в функцию как параметр. Назовем этот файл function.срр (листинг 13.3).

Листинг 13.3. Содержимое файла function.срр
// пока стек не пустой
// выводим число с вершины
// удаляем элемент из стека
void function (TStack &t) { while (!t.empty())
{ cout << "(double *)t.top() << endl:
double *p = (double *)t.pop();
delete p;
}
}



Проблем пока нет, но они появляются при подключении файла к нашей главной программе. Выясняется, что мы должны учитывать порядок следования директив #i nclude, чтобы все работало. Правильный порядок такой:
#include <iostream> using namespace std: #include "TStack.cpp" #include "function.cpp"



Стандартный файл iostream должен быть указан перед файлом function.cpp, так как в функции f () выполняется вывод в стандартный поток. Ранее должен быть включен и файл со стеком, так как функция f () его получает в качестве параметра. Порядок следования файлов TStack.cpp и iostream в данном случае может быть произвольным, но только потому, что в нашем стеке никак не используется стандартный ввод-вывод.
Налицо зависимость файлов друг от друга во время компиляции — ситуация крайне неприятная: мало того, что каждый раз транслируется объединенный текст, так еще мы должны «вручную» отслеживать связи между различными модулями. Это достижимо только для очень небольших программ, состоящих не более чем из пары десятков модулей, а дальше начинаются проблемы.
На ум приходит естественное решение — добавить в модуль function.cpp три первые строки из модуля main.cpp:
#include <iostream> using namespace std; #include "TStack.cpp"



Однако при трансляции тут же выясняется, что класс TStack определен дважды1. По стандарту в программе разрешается иметь несколько определений класса, но в разных единицах трансляции (см. п. п. 3.2/5 в [1]). А у нас получается двойное определение в одной единице — в модуле main.cpp. Действительно, после постановки всех наших файлов (про системные файлы пока умолчим) объединенный модуль main.cpp содержит следующие директивы #include:
#include <iostream> — включает системный файл iostream;
#include "TStack.cpp" в модуле main.cpp — включает класс TStack;
#include "function.cpp" в модуле main.cpp — включает файл function.cpp;
#include "TStack.cpp" в модуле function.cpp — включает класс TStack.



Таким образом, класс TStack оказывается определенным дважды. Справиться с этой проблемой нам опять поможет препроцессор: мы должны определить во включаемом файле «стража» включения. Для этого используется директива #def ine и директивы условной трансляции препроцессора. Обычно это делается так:
// myfile.h
#ifndef MYFILE // страж определен?
#define MYFILE // если нет - определяем
// содержимое файла
#endif // конец #ifndef



Первая строка часто пишется немного по-другому:
#if !defined( MYFILE ) // страж определен?



Однако сути дела это не меняет.
Когда препроцессор обрабатывает первую директиву, имя MYFILE (страж) не определено:
Обратите внимание, что с системным файлом ошибок не возникает!
#include "myfile.h"



Поэтому содержимое файла включается в обработку. Если эта директива встречается еще раз, то страж уже определен и содержимое файла пропускается.
Именно так организованы стандартные файлы, и поэтому не было проблем со стандартным файлом iostream. Например, начало стандартного файла math.h в интегрированной среде Borland С++ Builder 6 выглядит так:
/* math.h
Definitions for the math floating point package. ,
*/ /*
* C/C++ Run Time Library - Version 11.0
* Copyright (c) 1987, 2002 by Borland Software Corporation
* All Rights Reserved. */
/* $Revision: 9.17.2.6 $ */
#ifndef MATH_H // проверка стража
#define MATH_H // определение стража



Как видите, определен страж с именем МАТН_Н. Практически не отличается от
этого файла соответствующий файл системы Visual C++.NET 2003 (пропущены некоторые строки, не относящиеся к делу):

/***
¦math.h - definitions and declarations for math library *
* Copyright (c) Microsoft Corporation. All rights reserved. *
¦Purpose:
* This file contains constant definitions and external subroutine
* declarations for the math subroutine library.
* [ANSI/System V] *
* [public] ¦
* * * * /
#ifndef _INC_MATH #define _INC_MATH



В этой системе определен страж с именем _INC_MATH.
По негласному соглашению имена, определяемые в директиве #def i пе, пишутся прописными буквами — это позволяет по одному виду имени определить, что оно «принадлежит» препроцессору и «работает» только на стадии компиляции.
Наш файл TStack.cpp должен быть таким, как показано в листинге 13.4.

Листинг 13.4. Файл TStack.cpp со стражем
#ifndef __STACK // страж определен?
#define _STACK // определение стража
class TStack {
// определение класса
}:
#endif /* _STACK */ // конец ifndef



Теперь все работает правильно.
Опубликовал Kest January 15 2014 21:08:36 · 3 Комментариев · 3973 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Максим January 15 2014 22:26:00
По сути стражи включения я использую довольно редко в своей работе, но есть моменты, когда их использование вполне оправданно.

По мне так это дополнительные возможности самого языка, которые делают его более динамичным и гибким, особенно, когда требуется грамотная компоновка модулей при компиляции большого проекта.
Николай January 17 2014 18:55:25
Никогда не думал, что подключение файлов и библиотек влияет на работу программы, я файлы всегда подключал в произвольном порядке и ошибок не возникало, видимо при подключении своих файлов, я бы столкнулся со сложностями. Просто необходимо разобраться с препроцессорной обработкой, очень часто где встречалась, а я еще толком не знаю что и как там работает и какие команды за что отвечают, но с вашим сайтом думаю это не проблема! Спасибо, пример помог разобраться!
Илья January 18 2014 15:23:19
Николай, этот сайт вообще кладезь полезной информации, по крайней мере для меня. Мне он нравится потому что: 1 - Большое количество литературы, статей, а самое главное можно спросить совет у людей которые в этом действительно разбираются и понимают. Так что тут можно учиться и искать информацию, литературы предостаточно было бы желание как говориться. Если что-то не понимаешь можно спросить, и тебе подскажут. Мне как новичку в этом деле очень помогает. 2 – Общение. На сайте есть форум там можно найти друзей, которые тоже интересуются программированием или просто обсудить интересные новости с другими людьми.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Dbgridpack
Пятнашки и крести...
MiniChat
Файловый менеджер
Паскаль и Дельфи....
Crypt32
DateEdit
Email
Добавление к ссы...
Midi
PBEditPack
SynEdit
ShadelLabel
Comdrv
FreeSMS v1.3.1
CarGame [Исходник...
FilesInfo
Delphi. Учимся на...
Пример OpenGL гра...
Клавиатурный трен...

Топ загрузок
Приложение Клие... 100422
Delphi 7 Enterp... 84985
Converter AMR<-... 20062
GPSS World Stud... 11985
Borland C++Buil... 11408
Borland Delphi ... 8388
Turbo Pascal fo... 7008
Visual Studio 2... 4985
Калькулятор [Ис... 4631
FreeSMS v1.3.1 3530
Случайные статьи
Какие возможности ...
LOGIC (ЛОГИЧЕСКИЙ ...
Защита от вирусов ...
Определение версии...
Эти сумасшедшие па...
использования во в...
Модели управления ...
Убедитесь, что вы ...
Чтобы получить дос...
Линия тренда
Вообразите какого-...
Полный набор 16- и...
Интерфейсы и IDL
Выбор VPN для начи...
Служба RunAsСлужба...
Удаление экземпляр...
0 — NTLM
Установка шаблона ...
Потоки ввода-вывод...
Политика отключения
Конфигурация серве...
Небольшие изменени...
Теперь займемся ус...
Работа с фильтрами...
Протоколы группово...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?