我有Java背景,使用的是包,而不是名称空间。我习惯于将一起工作以形成完整对象的类放入包中,然后从该包中重用它们。但是现在我在用c++工作。
在c++中如何使用名称空间?您是为整个应用程序创建单个名称空间,还是为主要组件创建名称空间?如果是,如何从其他名称空间中的类创建对象?
我有Java背景,使用的是包,而不是名称空间。我习惯于将一起工作以形成完整对象的类放入包中,然后从该包中重用它们。但是现在我在用c++工作。
在c++中如何使用名称空间?您是为整个应用程序创建单个名称空间,还是为主要组件创建名称空间?如果是,如何从其他名称空间中的类创建对象?
当前回答
@marius
是的,你可以同时使用几个命名空间,例如:
using namespace boost;
using namespace std;
shared_ptr<int> p(new int(1)); // shared_ptr belongs to boost
cout << "cout belongs to std::" << endl; // cout and endl are in std
[2014年2月-(真的有那么长时间吗?):正如乔伊在下面指出的,这个特殊的例子现在是模棱两可的。Boost和std::现在各有一个shared_ptr.]
其他回答
@marius
是的,你可以同时使用几个命名空间,例如:
using namespace boost;
using namespace std;
shared_ptr<int> p(new int(1)); // shared_ptr belongs to boost
cout << "cout belongs to std::" << endl; // cout and endl are in std
[2014年2月-(真的有那么长时间吗?):正如乔伊在下面指出的,这个特殊的例子现在是模棱两可的。Boost和std::现在各有一个shared_ptr.]
我使用c++命名空间的方式与我在c#、Perl等中使用的方式相同。它只是标准库内容、第三方内容和我自己的代码之间的符号语义分离。我会将自己的应用程序放在一个名称空间中,然后将可重用的库组件放在另一个名称空间中进行分离。
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() ;
}
您甚至可以从不同的名称空间导入选择的符号,以构建您自己的自定义名称空间接口。我还没有找到它的实际用途,但在理论上,它很酷。
为了避免赘述,Mark Ingram已经说了一个使用名称空间的小技巧:
避免在头文件中使用“using namespace”指令——这会为导入该头文件的程序的所有部分打开命名空间。在实现文件(*.cpp)中,这通常不是大问题——尽管我更喜欢在函数级别上使用“using namespace”指令。
我认为命名空间主要用于避免命名冲突,而不一定用于组织代码结构。我主要用头文件/文件结构来组织c++程序。
有时在较大的c++项目中使用名称空间来隐藏实现细节。
using指令的附加说明: 有些人喜欢只对单个元素使用“using”:
using std::cout;
using std::endl;
我更喜欢为应用程序使用顶级名称空间,而为组件使用子名称空间。
使用来自其他名称空间的类的方式与java中的方式惊人地相似。 你可以使用“use NAMESPACE”,这类似于“import PACKAGE”语句,例如使用std。或者你指定包作为类的前缀,用“::”分隔,例如std::string。这类似于“java.lang”。字符串”。