何时使用命名空间或结构?

时间:2010-04-10 17:55:37

标签: c++ struct namespaces

我只是在http://www.cplusplus.com/doc/tutorial/namespaces/上阅读了一些内容。 它看起来像一个结构能够做同样的事情?或者甚至是一个类。也许有人可以更好地定义名称空间是什么,以及它与结构/类的区别?

6 个答案:

答案 0 :(得分:18)

命名空间和类类型不具备相同的功能。命名空间主要用于将类型和函数组合在一起以避免名称冲突,而类类型包含处理该数据的数据和操作。

要使用类必须将它们设置为静态来对函数和对象进行分组:

struct X {
    static void f();
};

如果没有static,您必须创建类类型的实例才能使用它们。命名空间在这里更适合:

namespace X {
    void f();
}

另一个重要的事情是using声明和指令:

namespace X {
    void f();
    void g();
}

void h() {
    using X::f;
    f(); // f() now visible in current scope
    using namespace X;
    f(); g(); // both visible
}

对于类类型,根本没有允许它的机制。

什么类类型为您提供了名称空间,您可以拥有多个具有不同状态的实例 - 如果您需要使用类类型。

答案 1 :(得分:7)

好吧,似乎每个人都在努力,所以我会添加自己的论点。

首先,namespacestruct是完全不同的野兽:它们具有不同的语法和不同的语义。

显而易见:

  • a struct引入了一种类型,您可以将其用作模板参数
  • namespace可以分布在多个文件中

句法:

  • 两者都可以是“别名”,名称空间为namespace ns = mylong::name::space;,结构为typedef mylong::name::Space lilstruct;
  • ADL(或Argument Dependent Lookup)是为名称空间定制的

语义:

  • a namespace只定义了符号定义的范围,它允许将一起工作的对象(类和自由函数)组合在一起,同时将它们隔离到世界其他地方(名称冲突)。因此,它通常代表项目中的逻辑工作单元(对于小项目,只有一个命名空间)。
  • structclass定义了数据与作用于它的方法之间的逻辑绑定,这是封装的基石。它通常有一个明确的责任和一些不变量。

请注意,有时structclass仅用于将没有任何逻辑的对象绑定在一起,例如struct Person { std::string name, firstName; };

话虽如此:C ++中structstatic方法没有意义。这只是来自Java或C#的反转以及他们的“纯粹”OO方法。 C ++支持自由函数,所以没有必要不使用它们,特别是因为它更适合封装(它们无法访问私有/受保护的部分,所以你不能搞乱一个不变量而且它们不依赖于该类的代表。)。

答案 2 :(得分:2)

创建自己的库时,通常最好将所有导出的函数和类命名为。

这样,如果某人包含您的图书馆,他们就不会污染他们的名称空间,而且名称冲突的可能性也会降低。

答案 3 :(得分:2)

如果可以使用命名空间,请使用命名空间。

结构不仅仅是定义范围。它定义了一种类型。

答案 4 :(得分:1)

在C ++中,结构与类完全相同,但默认情况下结构是公共的。课程是私人的。因此,只要您想要将自由函数组合在一起,就可以使用命如果要对数据和函数进行分组,请使用结构/类,并可选择围绕它使用命名空间。
请注意,如果将函数放在结构中,那么当您想要调用这些函数时,您必须拥有结构的实例,除非它们是静态的。

答案 5 :(得分:1)

如果您不希望人们在您的类中使用C ++的“使用”功能,可能危险且在复杂代码中通常不明智,那么继续使用struct with静。

换句话说:如果你的函数总是用“group :: function”引用,那么你可以通过声明为结构来装入你的用户。

In addition, and importantly, you can forward-declare structs in older versions of C++.在C ++ 11之前,您无法使用命名空间。

考虑一下:

std::string out zip::pack(const std::string &in)
std::string out zip::unpack(const std::string &in)

在这种情况下,要求用户指定zip ::才有意义。这是一个简短,具体和信息丰富的。没有它,底层函数的名称是模糊的。使用带静态的结构。

考虑一下:

std::string out CorpDataUtils::zipPack(const std::string &in)
std::string out CorpDataUtils::zipUnpack(const std::string &in)

这些当然应该在命名空间中。命名空间名称很长,而且没有信息,可能更多地与维护它的人的组织有关 - 这很好......但实际上它应该是命名空间...而不是结构。