0

我熟悉以下命名空间的使用。

在头文件(例如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;
}

但是,在我拥有的头文件中,我看到除了其他名称空间之外namespace people还有其他名称空间的接口(例如namespace dogs)。并且这些名称空间没有在people.cpp文件中定义。

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

所以,我假设namespace dogs在 2people.h" 文件中有另一个功能,但我不知道它是什么功能。有人可以帮我吗?

添加

我试图理解的代码不是我写的,它工作正常。所以,这应该是有道理的。可能是我不够清楚。所以,我试着举个例子:

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

namespace etet
{
    class date;
}

namespace xsystem{
    class estimation_module;
}

namespace people {
   a_lot_of_different_stuff;
}

然后people.cpp定义了属于 people 命名空间的所有方法。

4

2 回答 2

2

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

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

但是,这与命名空间非常不同。命名空间可以在相同和不同的翻译单元中多次引入,而不是每次都是相同的标记。这样的事情完全没问题:

namespace bar {
  void baz();
  struct x;
}
// some stuff
namespace bar {
  void do_something(x);
}

每次出现都会namespace bar向该命名空间引入一些声明。

您通常会在同一个命名空间中定义许多类。这些类的每个标头都会将namespace whatever { ... }类定义引入该命名空间。

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

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

现在,这class需要知道命名空间dog中的类型dogs。一种方法是这样做#include "dogs.h"。然而,由于pet_dog它只是一个指针,我们可以使用不完整的类型,所以我们可以dog像这样转发声明:

namespace dogs {
  class dog;
}

namespace people {
  class person {
    dogs::dog* pet_dog;
  };
}
于 2013-02-26T13:48:12.900 回答
2

“命名空间接口”是一个误导性概念。命名空间只是在一个姓氏下组合在一起的一堆名字(比如你​​和你的兄弟姐妹)。它没有“接口”,因为没有命名空间“对象”。

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

void people::setName(str Name) {
   something_1;
}

完全等同于

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

  void setName(str Name) {
     something_1;
  }
}

可能是这更熟悉,也可能不是。标头声明了 cpp 中不存在的函数这一事实,仅意味着它们可能存在于另一个中。

namespace name { ..... }关于声明可以在许多文件中重复的事实,每个文件都包含各种功能是完全正常的,因为namespace关键字没有声明对象。它只是分组名称。而且 - 事实上 - 说命名空间是“声明的”是一种常见的语言滥用。声明的是命名空间的名称。

并且在不同地方声明的不同名称可以属于同一个组。这没有什么神秘之处。

您的词典让我觉得您将namespaces 与classes 和structs混淆了

添加:

在您澄清之后,看起来a_lot_of_different_stuff包含使用etet::date和的声明xsystem::estimation_module;

编译器必须知道这些名称(并且只有名称),但标头不能递归地包含它们各自的标头,因为它们很可能已经包含people.h

一个典型的“课程参考”问题,就像这里一样,但涉及不同的命名空间。

于 2013-02-26T13:48:47.417 回答