C++ 如何在C++;?

C++ 如何在C++;?,c++,namespaces,C++,Namespaces,我来自Java背景,使用包,而不是名称空间。我习惯于将一起工作以形成完整对象的类放入包中,然后在以后从该包中重用它们。但是现在我在C++中工作。 C++中如何使用命名空间?您是为整个应用程序创建一个名称空间,还是为主要组件创建名称空间?如果是这样,如何从其他名称空间中的类创建对象?名称空间本质上是包。它们可以这样使用: namespace MyNamespace { class MyClass { }; } 然后在代码中: MyNamespace::MyClass* pClass

我来自Java背景,使用包,而不是名称空间。我习惯于将一起工作以形成完整对象的类放入包中,然后在以后从该包中重用它们。但是现在我在C++中工作。
<> C++中如何使用命名空间?您是为整个应用程序创建一个名称空间,还是为主要组件创建名称空间?如果是这样,如何从其他名称空间中的类创建对象?

名称空间本质上是包。它们可以这样使用:

namespace MyNamespace
{
  class MyClass
  {
  };
}
然后在代码中:

MyNamespace::MyClass* pClass = new MyNamespace::MyClass();
或者,如果希望始终使用特定命名空间,可以执行以下操作:

using namespace MyNamespace;

MyClass* pClass = new MyClass();
编辑:按照前面所说的,我倾向于根本不使用“使用名称空间x”语法,我通常在实例化对象时显式指定名称空间(即我展示的第一个示例)


正如您所要求的,您可以使用任意多的名称空间。

一般来说,如果我认为可能与其他库存在函数或类型名冲突,我会为代码体创建名称空间。它还有助于将代码命名为ala。

我更喜欢为应用程序使用顶级名称空间,为组件使用子名称空间

使用其他名称空间中的类的方式与java中的方式惊人地相似。 您可以使用类似于“import PACKAGE”语句的“use NAMESPACE”,例如use std。或者将包指定为以“:”,例如std::string分隔的类的前缀。这类似于java中的“java.lang.String”。

@

是的,一次可以使用多个名称空间,例如:

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
使用名称空间boost;
使用名称空间std;
共享_ptr p(新整数(1));//共享_ptr属于boost
在Java中:

package somepackage;
class SomeClass {}
在C++中:

namespace somenamespace {
    class SomeClass {}
}
使用它们,Java:

import somepackage;
和C++:

using namespace somenamespace;

< P>也可以说,完整的名字是java的“SoPaxkG.SomeClass”和C++的“SimeMeMeStay::SomeClass”。使用这些约定,您可以像在Java中习惯的那样进行组织,包括为名称空间生成匹配的文件夹名称。文件夹->包和文件->类的要求并不存在,因此您可以从包和名称空间中独立命名文件夹和类。

为了避免说所有的话,Mark Ingram已经说过使用名称空间的小技巧:

避免在头文件中使用“using namespace”指令-这将为导入此头文件的程序的所有部分打开名称空间。在实现文件(*.cpp)中,这通常不是什么大问题-尽管我更喜欢在函数级别使用“using namespace”指令

我认为名称空间主要用于避免命名冲突,而不一定用于组织代码结构。我将主要用头文件/文件结构组织C++程序。

有时在较大的C++项目中使用命名空间来隐藏实现细节。

使用指令的附加说明: 有些人更喜欢对单个元素使用“using”:

using std::cout;  
using std::endl;

另外,请注意,您可以添加到命名空间。举个例子就更清楚了,我的意思是你可以:

namespace MyNamespace
{
    double square(double x) { return x * x; }
}
在文件
square.h
中,以及

namespace MyNamespace
{
    double cube(double x) { return x * x * x; }
}

在文件
cube.h
中。这定义了一个名称空间<代码> MyMaSeSts< /C++ >(即,可以跨多个文件定义一个单一命名空间)。它们不提供任何包在java中的封装,所以你可能不会使用它们。

< P>我用C++的名称空间和C语言、Perl中的方法一样,只是在标准的库、第三方的东西和我自己的代码之间符号的语义分离。我将自己的应用程序放在一个命名空间中,然后在另一个命名空间中再使用一个C++ C++组件来进行分离。

< P> java和C++之间的另一个区别,就是C++中,名称空间层次不需要对文件系统布局进行编码。因此,我倾向于将整个可重用库放在一个名称空间中,并将库中的子系统放在子目录中:

#include "lib/module1.h"
#include "lib/module2.h"

lib::class1 *v = new lib::class1();
只有在可能存在名称冲突的情况下,我才会将子系统放在嵌套的名称空间中。

您还可以在函数中包含“使用名称空间…”,例如:

void test(const std::string& s) {
    using namespace std;
    cout << s;
}
void测试(const std::string&s){
使用名称空间std;
库特

我见过的大型C++项目几乎没有使用过多个命名空间(例如,Boost库)。 实际上boost使用了大量的名称空间,通常boost的每个部分都有自己的内部工作名称空间,然后可能只将公共接口放在顶级名称空间boost中

我个人认为,代码库越大,名称空间就越重要,即使在单个应用程序(或库)中也是如此

namespace ns {

class A
{
};

}

void print(A a)
{
}
我经常使用的名称空间的另一个用途(并非双关语)是匿名名称空间:

namespace {
  const int CONSTANT = 42;
}
这基本上与:

static const int CONSTANT = 42;

使用匿名命名空间(而不是静态)是代码和数据在C++中当前编译单元中可见的推荐方式。

< P>不要听每个人告诉你命名空间只是名称空间。< /P> 它们很重要,因为编译器认为它们应用了接口原理。基本上,可以通过一个示例来解释:

namespace ns {

class A
{
};

void print(A a)
{
}

}
如果要打印对象,代码如下:

ns::A a;
print(a);

注意,调用函数时,我们没有明确地提到命名空间。这是接口原则:C++考虑一个函数,将一个类型作为一个参数作为该类型的接口的一部分,因此不必指定命名空间,因为参数已经暗示了命名空间。

namespace ns {

class A
{
};

}

void print(A a)
{
}
现在,为什么这个原则很重要?假设类A的作者没有为这个类提供print()函数。你必须自己提供一个。因为你是一个优秀的程序员,你将在中定义这个函数
namespace AAA
{
   void doSomething() ;
}

namespace BBB
{
   void doSomethingElse() ;
}

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

void doSomethingAgain()
{
   CCC::doSomething() ;
   CCC::doSomethingElse() ;
}
Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally::TheClassName foo;
Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally::AnotherClassName bar;
namespace Shorter = Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally;
Shorter::TheClassName foo;
Shorter::AnotherClassName bar;