C++ 为什么头文件中需要名称空间?

C++ 为什么头文件中需要名称空间?,c++,interface,namespaces,header-files,C++,Interface,Namespaces,Header Files,我熟悉名称空间的以下用法 在头文件(例如people.h)中,我描述了名称空间的接口。例如: namespace people{ int getAge(str Name); void setName(str Name); } 然后在people.cpp中,我从空间名称定义方法: #include "people.h" int people::getAge(str Name) { something_1; something_2; } void people::setN

我熟悉名称空间的以下用法

在头文件(例如
people.h
)中,我描述了名称空间的接口。例如:

namespace people{
   int getAge(str Name);
   void setName(str Name);
}
然后在
people.cpp
中,我从空间名称定义方法:

#include "people.h"
int people::getAge(str Name) {
   something_1;
   something_2;
}

void people::setName(str Name) {
   something_1;
}
但是,在我拥有的头文件中,我看到除了
名称空间people
之外,还有其他名称空间的接口(例如
名称空间dogs
)。而且这些名称空间没有在
people.cpp
文件中定义

因此,我假设(出于某种奇怪的原因)将
名称空间dogs
的接口放入
people.h
中,然后在“dogs.cpp”文件中定义名称空间dog。换句话说,我假设在两个不同的cpp文件中定义了两个不同的名称空间,但在一个头文件中描述了它们的接口。然而,这个假设似乎是错误的,因为我发现有许多头文件声明“名称空间狗”

因此,我假设2people.h文件中的
名称空间狗
有另一个函数,但我不知道它是什么函数。有人能帮我吗

已添加

我试图理解的代码不是我写的,它工作得很好。因此,它应该是有意义的。可能是我不够清楚。因此,我尝试给出一个示例:

在头文件(
people.h
)中,我有:


然后,
people.cpp
定义属于人员名称空间的所有方法。

您混淆了名称空间和类。通常,类定义出现在头文件(
.h
)中,其成员函数的实现出现在相应的实现文件(
.cpp
)中

命名空间的工作方式与
不同。如果在多个翻译单元中定义了
,则所有翻译单元中必须具有完全相同的标记。您甚至不能对成员重新排序,即使这会导致完全相同的类。使用上述头文件很容易满足此要求。每个翻译需要类
foo
的单元包含
foo.h
的内容,因为它们在需要时包含“foo.h”。当然,它们都包含与
foo
完全相同的
foo
定义,因为它们都包含
foo.h

但是,这与名称空间非常不同。可以在相同和不同的转换单元中多次引入名称空间,而不必每次都使用相同的标记。类似这样的情况完全可以:

namespace bar {
  void baz();
  struct x;
}
// some stuff
namespace bar {
  void do_something(x);
}
每次出现
名称空间栏
都会向该名称空间引入一些声明

在同一个名称空间中通常会定义许多类。这些类的每个头都将执行
名称空间{…}
并将类定义引入该名称空间

有时,您甚至希望在一个头文件中向多个名称空间或嵌套名称空间引入内容。没有什么可以阻止您这样做。这样做的一种可能情况是,如果您希望从另一个名称空间转发声明内容。假设您在
people.h
中定义了一个类,如下所示:

namespace people {
  class person {
    dogs::dog* pet_dog;
  };
}
namespace dogs {
  class dog;
}

namespace people {
  class person {
    dogs::dog* pet_dog;
  };
}
现在,这个
类需要知道
dogs
命名空间中的类型
dog
。一种方法是
#包括“dogs.h”
。但是,由于
pet\u dog
只是一个指针,我们可以使用不完整的类型,因此我们可以像这样向前声明
dog

namespace people {
  class person {
    dogs::dog* pet_dog;
  };
}
namespace dogs {
  class dog;
}

namespace people {
  class person {
    dogs::dog* pet_dog;
  };
}

您混淆了名称空间和类。通常,类定义出现在头文件(
.h
)中,其成员函数的实现出现在相应的实现文件(
.cpp
)中

命名空间的工作方式与
不同。如果在多个翻译单元中定义了
,则所有翻译单元中必须具有完全相同的标记。您甚至不能对成员重新排序,即使这会导致完全相同的类。使用上述头文件很容易满足此要求。每个翻译需要类
foo
的单元包含
foo.h
的内容,因为它们在需要时包含“foo.h”
。当然,它们都包含与
foo
完全相同的
foo
定义,因为它们都包含
foo.h

但是,这与名称空间非常不同。可以在相同和不同的转换单元中多次引入名称空间,而不必每次都使用相同的标记。类似这样的情况完全可以:

namespace bar {
  void baz();
  struct x;
}
// some stuff
namespace bar {
  void do_something(x);
}
每次出现
名称空间栏
都会向该名称空间引入一些声明

在同一个名称空间中通常会定义许多类。这些类的每个头都将执行
名称空间{…}
并将类定义引入该名称空间

有时,您甚至希望在一个头文件中向多个名称空间或嵌套名称空间引入内容。没有什么可以阻止您这样做。这样做的一种可能情况是,如果您希望从另一个名称空间转发声明内容。假设您在
people.h
中定义了一个类,如下所示:

namespace people {
  class person {
    dogs::dog* pet_dog;
  };
}
namespace dogs {
  class dog;
}

namespace people {
  class person {
    dogs::dog* pet_dog;
  };
}
现在,这个
类需要知道
dogs
命名空间中的类型
dog
。一种方法是
#包括“dogs.h”
。但是,由于
pet\u dog
只是一个指针,我们可以使用不完整的类型,因此我们可以像这样向前声明
dog

namespace people {
  class person {
    dogs::dog* pet_dog;
  };
}
namespace dogs {
  class dog;
}

namespace people {
  class person {
    dogs::dog* pet_dog;
  };
}
“名称空间接口”是一个误导性的概念。名称空间只是在一个姓氏(如您和您的兄弟姐妹)下组合在一起的一堆名称。它没有“接口”,因为没有名称空间“obejct”

完全等同于

#include "people.h"
namespace people
{
  int getAge(str Name) {
     something_1;
     something_2;
  }

  void setName(str Name) {
     something_1;
  }
}