Должен ли я включить заголовочный файл в пространство имен? - PullRequest
7 голосов
/ 19 марта 2012

В настоящее время я работаю над фреймворком c и хочу встроить в него пакет c ++. Однако возникает множество конфликтов имен. Поэтому я решил добавить пространство имен в исходный код C ++. Теперь вопрос в том, должен ли я переместить #include "header.h" в блок namespace {}? Я просто потратил некоторое время, чтобы выяснить ошибку, которая возникла из следующих кодов.

Исходный код C ++

В часах

#include <unistd.h>
struct File 
{
     void func(int fd);
}; 

В a.cpp

#include "a.h"
void File::func(int fd)
{
    ::close( fd );
}

И я добавил пространство имен вот так

Новый a.h ​​

namespace MyAddedNameSpace 
{ 
    #include <unistd.h>
    struct File 
    {
        void func(int fd);
    }; 
}

Новый a.cpp

#include "a.h"
namespace MyAddedNameSpace 
{
    void File::func(int fd)
    {
        ::close( fd );
    }
}

И компилятор жалуется, что :: close () не был объявлен.

Причина, по которой я поместил директиву #include в блок пространства имен, заключается в том, что импортированный мной пакет c ++ также использует флаг #ifndef для включения файлов заголовков следующим образом. Поэтому я думаю, что самый простой способ - поместить все коды в блок пространства имен {}

#ifndef 
    #include <header1.h> 
    #include <header2.h>
    ...
#else 
    #include <header3.h>
    #include <header4.h>
    ...
#endif

Теперь я решил эту проблему, добавив дополнительную строку в файл cpp

#include <unistd.h>  //new added line 
#include "a.h"
namespace MyNameSpace 
{
    void File::func(int fd)
    {
        ::close( fd );
    }
}

Но я не удовлетворен этим решением, так как заголовок unistd.h уже был включен в a.h, но внутри пространства имен MyAddedNameSpace, или я должен добавить префикс MyNameSpace ко всем вызовам функций, когда компилятор жалуется, что такая функция не объявлена?

Спасибо за ответ.

Ответы [ 2 ]

26 голосов
/ 19 марта 2012

НЕ СЛЕДУЕТ помещать директивы #include в свое собственное пространство имен. Что вы сделали, так это поместили все содержимое unistd.h в ваше пространство имен; таким образом, то, что раньше было (и должно остаться!) ::close(), теперь объявлено как MyAddedNameSpace::close(). Это НЕ то, что вы хотите.

Ваше «решение» добавления строки #include <unistd.h> в верхней части файла .cpp устраняет проблему, но только для этого одного файла .cpp. То, что вы сделали, это правильно включили заголовок библиотеки (без вашего пространства имен), а затем, когда ваш заголовок (ах) включен, он снова делает #include <unistd.h> (на этот раз в вашем пространстве имен ), но на этот раз включенные охранники в этом файле предотвращают его повторную обработку. Так что для этого .cpp файла вы в порядке, но любой другой файл, который имеет #include <a.h>, будет иметь ту же проблему, что и у вас изначально.

Может быть редкий случай, когда у вас есть веская причина для использования #include в вашем собственном пространстве имен, но вы, скорее всего, будете включать один из ваших собственных заголовков (или некоторый другой файл) - НЕ заголовок библиотеки! - и даже тогда это, вероятно, не идеальное решение.

В ч.ч

#include <unistd.h>

namespace MyAddedNameSpace {

struct File
{
  void func(int fd);
};

}

В a.cpp

#include "a.h"

namespace MyAddedNameSpace {

void File::func(int fd)
{
  ::close( fd );
}

}
0 голосов
/ 19 марта 2012

Обычно достаточно поместить директиву using namespace в файл .cpp.Вот так:

using namespace MyAddedNameSpace;

    void File::func(int fd)
    {
        close( fd );
    }

Надеюсь, это поможет ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...