Чтение онлайн

на главную

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

Неудивительно, что если включить в myheader.h какое-либо определение, использующее членов

A
, то потребуется включить через
#includ
e заголовок для
А
. Это требуется для того, чтобы компилятор мог проверить сигнатуру используемой функции-члена
А
или тип переменной-члена
А
. Вот иллюстрация кода, требующего
#include
.

#include "a.h"

class B {

public:

 void f(const A& a) {

foo_ = a.getVal; //
требуется знать, допустимо ли a.getVal

 }

}

// ...

В общем случае используйте предварительное объявление тогда, когда это позволяет снизить количество

#include
, что отражается на времени компиляции.

2.4. Предотвращение конфликта имен с помощью пространств имен

Проблема

В несвязанных между собой модулях обнаружены конфликтующие имена или требуется заранее избежать возможности таких конфликтов, создав логические группы кода.

Решение

Для структурирования кода используйте пространства имен. С помощью пространств имен можно объединять большие группы кода, находящиеся в разных файлах, в единое пространство имен. Для разбиения больших модулей на подмодули можно использовать вложенные пространства имен, и потребители вашего модуля смогут выборочно открывать элементы вашего пространства имен, которые им требуются. Пример 2.5 показывает несколько способов использования пространства имен.

Пример 2.5. Использование пространств имен

// Devices.h

#ifndef DEVICES_H__

#define DEVICES_H__

#include <string>

#include <list>

namespace hardware {

 class Device {

 public:

Device: uptime_(0), status_("unknown") {}

unsigned long getUptime const;

std::string getStatus const;

void reset;

 private:

unsigned long uptime_;

std::string status_;

 };

 class DeviceMgr {

 public:

void getDeviceIds(std::list<std::string>& ids) const;

Device getDevice(const std::string& id) const;

// Other stuff...

 };

}

#endif // DEVICES_H__

// Devices.cpp

#include "Devices.h"

#include <string>

#include <list>

namespace hardware {

 using std::string;

 using std::list;

 unsigned long Device::getUptime const {

return(uptime__);

 }

 string Device::getStatus const {

return(status_);

 }

 void DeviceMgr::getDeviceIds(list<string>& ids) const {}

 Device DeviceMgr::getDevice(const string& id) const {

Device d;

return(d);

 }

}

// DeviceWidget.h

#ifndef DEVICEWIDGET_H__ #define DEVICEWIDGET_H__

#include "Devices.h"

namespace ui {

 class Widget {/*... */ };

 class DeviceWidget : public Widget {

 public:

DeviceWidget(const hardware::Device& dev) : device_(dev) {}

// Some other stuff

 protected:

hardware::Device device_;

 };

}

#endif // DEVICEWIDGET_H__

// main.cpp

#include <iostream>

#include "DeviceWidget.h"

#include "Devices.h"

int main {

 hardware::Device d;

 ui::DeviceWidget myWidget(d);

 // ...

}

Обсуждение

Пример 2.5

более сложен, но давайте разберем его по частям, так как он иллюстрирует несколько ключевых моментов, связанных с пространствами имен. Представьте, что вы пишете управляющее приложение, которое должно взаимодействовать с различным оборудованием. С целью устранения конфликтов имен вы можете разбить это приложение на два или более пространств имен или просто разделить его логически на две части.

Вначале рассмотрим файл Devices.h. Он содержит пару классов, которые управляют элементами оборудования, —

Device
и
DeviceMgr
. Однако они не должны находиться в глобальном пространстве имен (что означало бы, что их имена видны в любом месте программы), так что я поместил их в пространство имен
hardware
.

#ifndef DEVICES_H__ // см. рецепт 2.0

#define DEVICES_H__

#include <string>

Поделиться:
Популярные книги

Искушение генерала драконов

Лунёва Мария
2. Генералы драконов
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Искушение генерала драконов

Купеческая дочь замуж не желает

Шах Ольга
Фантастика:
фэнтези
6.89
рейтинг книги
Купеческая дочь замуж не желает

Измена. Свадьба дракона

Белова Екатерина
Любовные романы:
любовно-фантастические романы
эро литература
5.00
рейтинг книги
Измена. Свадьба дракона

Расческа для лысого

Зайцева Мария
Любовные романы:
современные любовные романы
эро литература
8.52
рейтинг книги
Расческа для лысого

Пустоши

Сай Ярослав
1. Медорфенов
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Пустоши

Гром над Империей. Часть 2

Машуков Тимур
6. Гром над миром
Фантастика:
фэнтези
попаданцы
5.25
рейтинг книги
Гром над Империей. Часть 2

Князь

Шмаков Алексей Семенович
5. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
5.00
рейтинг книги
Князь

Газлайтер. Том 4

Володин Григорий
4. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 4

Инквизитор Тьмы 2

Шмаков Алексей Семенович
2. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы 2

Черный дембель. Часть 1

Федин Андрей Анатольевич
1. Черный дембель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черный дембель. Часть 1

Школа Семи Камней

Жгулёв Пётр Николаевич
10. Real-Rpg
Фантастика:
фэнтези
рпг
5.00
рейтинг книги
Школа Семи Камней

Ваше Сиятельство 3

Моури Эрли
3. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ваше Сиятельство 3

Последний попаданец 5

Зубов Константин
5. Последний попаданец
Фантастика:
юмористическая фантастика
рпг
5.00
рейтинг книги
Последний попаданец 5

Под маской моего мужа

Рам Янка
Любовные романы:
современные любовные романы
5.67
рейтинг книги
Под маской моего мужа