我有Java背景,使用的是包,而不是名称空间。我习惯于将一起工作以形成完整对象的类放入包中,然后从该包中重用它们。但是现在我在用c++工作。

在c++中如何使用名称空间?您是为整个应用程序创建单个名称空间,还是为主要组件创建名称空间?如果是,如何从其他名称空间中的类创建对象?


当前回答

在Java中:

package somepackage;
class SomeClass {}

在c++中:

namespace somenamespace {
    class SomeClass {}
}

使用它们,Java:

import somepackage;

和c++:

using namespace somenamespace;

此外,全名是“somepackage”。用于Java的SomeClass和用于c++的somenamespace::SomeClass。使用这些约定,您可以像在Java中一样进行组织,包括为名称空间创建匹配的文件夹名称。但是没有文件夹->包和文件->类的要求,因此您可以根据包和名称空间独立地命名文件夹和类。

其他回答

注意,c++中的命名空间实际上只是一个名称空间。它们不提供Java包所提供的任何封装,因此您可能不会经常使用它们。

性病::cout

的 前缀std::表示 名称cout和endl是 在命名空间内定义 命名std。允许命名空间 我们要避免无意的碰撞 在我们定义的名称之间 以及使用这些相同的名字 在图书馆里。所有的名字 由标准库定义 都在stdnamespace中。写作std:: Cout使用作用域操作符 (运算符::)来表示我们 要使用名称cout 定义在 名称空间性病。 会显示一个更简单的方法 从库中访问名称。

一般来说,如果我认为一段代码可能与其他库有函数或类型名称冲突,我会为它创建一个名称空间。它也有助于品牌代码,ala boost::。

Vincent Robert在他的评论中是正确的,你如何在c++中正确使用名称空间?

使用命名空间

命名空间的使用至少有助于避免名称冲突。在Java中,这是通过“org。域名”的成语(因为它假定一个人不会使用他/她自己的域名以外的任何东西)。

在c++中,您可以为模块中的所有代码指定一个名称空间。例如,对于模块MyModule.dll,可以将其代码命名为MyModule。我在其他地方看到有人使用MyCompany::MyProject::MyModule。我想这有点过分了,但总的来说,在我看来这是正确的。

使用“使用”

Using应该非常谨慎地使用,因为它有效地将一个(或所有)符号从名称空间导入到当前名称空间。

在头文件中这样做是邪恶的,因为你的头文件会污染包括它在内的所有源代码(这让我想起了宏…),甚至在源文件中,在函数作用域之外也是糟糕的风格,因为它会在全局作用域导入命名空间中的符号。

使用"using"最安全的方法是导入选定的符号:

void doSomething()
{
   using std::string ; // string is now "imported", at least,
                       // until the end of the function
   string a("Hello World!") ;
   std::cout << a << std::endl ;
}

void doSomethingElse()
{
   using namespace std ; // everything from std is now "imported", at least,
                       // until the end of the function
   string a("Hello World!") ;
   cout << a << endl ;
}

您将在教程或示例代码中看到大量“使用名称空间std;”。原因是为了减少符号的数量,使阅读更容易,而不是因为这是一个好主意。

Scott Meyers不鼓励“使用命名空间std;”(我不记得具体是哪本书了,但如果有必要,我可以找到它)。

名称空间组成

名称空间不仅仅是包。另一个例子可以在Bjarne Stroustrup的“c++编程语言”中找到。

在“特别版”中,在8.2.8命名空间组合中,他描述了如何将两个命名空间AAA和BBB合并为另一个名为CCC的命名空间。因此CCC成为AAA和BBB的别名:

namespace AAA
{
   void doSomething() ;
}

namespace BBB
{
   void doSomethingElse() ;
}

namespace CCC
{
   using namespace AAA ;
   using namespace BBB ;
}

void doSomethingAgain()
{
   CCC::doSomething() ;
   CCC::doSomethingElse() ;
}

您甚至可以从不同的名称空间导入选择的符号,以构建您自己的自定义名称空间接口。我还没有找到它的实际用途,但在理论上,它很酷。

我使用c++命名空间的方式与我在c#、Perl等中使用的方式相同。它只是标准库内容、第三方内容和我自己的代码之间的符号语义分离。我会将自己的应用程序放在一个名称空间中,然后将可重用的库组件放在另一个名称空间中进行分离。