#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>

#include <list>

namespace hardware {

 class Device {

  // ...

 };

 class DeviceMgr {

  // ...

 };

}

#endif // DEVICES_H__

Этот механизм прост: «оберните» все, что требуется поместить в пространство имен, в блок namespace.

Приведенный выше фрагмент — это объявление Device и DeviceMgr, но нам также требуется подумать об их реализациях, которые находятся в файле Devices.cpp. И снова оберните все в блок namespace — он будет добавлен к уже имеющемуся содержимому этого пространства имен.

#include 'Devices.h'

#include <string>

#include <list>

namespace hardware {

 using std::string;

 using std::list;

 // Реализация Device и DeviceMgr

}

В данный момент пространство имен hardware содержит все, что требуется. Все, что осталось, — это где-то его использовать. Для этого имеется несколько способов. Способ, который был использован в примере 2.5, состоит в указании полного имени класса Device, включая пространство имен, как здесь.

#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) {}

  // Other stuff...

 protected:

  hardware::Device device_;

 };

}

#endif // DEVICEWIDGET_H__

Также я использую этот способ в main в main.cpp.

int main() {

 hardware::Device d;

 ui::DeviceWidget myWidget(d);

}

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

При использовании подхода с указанием полных имен классов, включающих пространство имен, вы быстро устанете вводить код. Имеется пара способов устранить эту проблему. Для полного имени типа с помощью ключевого слова using можно создать псевдоним.

using hardware::Device;

int main() {

 Device d; // Пространство имен не требуется

 ui::DeviceWidget myWidget(d);

}

В последующем коде вместо ввода полного имени можно просто сослаться на этот псевдоним. Или можно с помощью using импортировать все содержимое пространства имен, а не только один содержащийся в нем тип.

using namespace hardware;

int main() {

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

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

Отметить Добавить цитату