命名空间和C++

7

我注意到在C++中,命名空间很少使用,而在.NET中很常见。这是有特别原因吗?

另外,我想知道其他人是否看到命名空间在C++中被广泛使用。

编辑:实际上,我指的是自定义应用程序,而不是标准库(如STL或任何其他东西)。


6
我想知道你在看哪些代码。除了“主要代码”以外,我所做的一切都在命名空间中。 - GManNickG
@GMan:嗯,比如说,Scott Meyers并不是特别喜欢它们(或者至少在他九年前写这篇文章的时候是这样)。 - James McNellis
3
Meyers并不是在抱怨命名空间的概念,而是关于为了将它们加入语言中所需做出的妥协(Koenig查找)感到不满。 - James Curran
2
@James Curran:嗯,这个问题是关于命名空间和C++的。引用Meyers的帖子:“如果由我决定,我们将完全摒弃命名空间...我认为它们被创建来解决一个在很大程度上不存在的问题。” 这并不是反对命名空间的概念(可以通过其他方式实现,例如使用特定于库的前缀),但是反对C++命名空间实现,其中Koenig查找和其他细微差别是基本部分。 - James McNellis
9个回答

11

在C++语言中,命名空间是在初始实现之后一段时间才添加的,因此有很多应用程序代码并没有使用它们。因此,由于它们的晚加入,所有标准库都被放入了一个命名空间中。因此,通过简单的using namespace std;,如果您想要的话就可以忽略命名空间。

另一方面,在C#中,命名空间从一开始就很重要,并且库被分成了许多命名空间。此外,每个人都使用的创建初始代码的向导会默认将类放入一个命名空间中。这迫使人们更加注意命名空间。


7

C++中的命名空间与.Net、ActionScript和Java(共享相同概念)中的命名空间完全不同。它们根本不是相同的概念。

在C++中,命名空间主要用于允许将多个类型和函数封装在一个命名上下文中,即命名空间。它仅涉及命名和访问名称。

在.Net、ActionScript和Java中,命名空间更多地涉及模块而不是名称。它们强制开发人员将代码组织在单独的命名空间中,每个命名空间都与一个目的、上下文有关。由于这些语言是动态的(而不是像C++一样静态),命名空间允许类型向代码进行后期绑定,使编译速度快,因为您只需要在文件中使用类型的规范名称(命名空间+名称)。

在C++中,没有模块概念,只有互相不知道的编译单元。

现在谈到它们的使用,通常最好在C++中使用命名空间来封装模块(可执行文件或dll/so)、一些实现代码或任何有用的子代码部分。话虽如此,大多数情况下最好不要有太深的命名空间层次结构。由于历史原因,很多C++开发人员很长时间以来甚至不知道C++有一个名为命名空间的特性。现在我们所谓的“现代C++”建议您了解它,但是很多旧的C++代码今天仍在使用,也许这就是您在谈论命名空间时看到的内容。

C++中的命名空间是与其他语言不同的功能,这也使得它在代码中的编写更或多或少明显。事实上,它是如此不同,以至于您将无法完全以相同的方式管理它,这使得代码在从.Net等语言转换过来时真的很难理解。因此,您不应该在不同的语言之间以相同的方式考虑命名空间,它们是真正不同的概念。


2
在 .Net、ActionScript 和 Java 中,命名空间更多地涉及模块而非名称。这对于 .net 来说绝对是不准确的。命名空间的成员可以在多个程序集中定义,一个程序集也可以包含多个命名空间的定义。实际上,这与 C++ 中命名空间的工作方式非常相似。Java 稍有不同,因为命名空间默认情况下会告知 .class 文件的文件系统位置(暂时忽略 jar),但即使如此,模块单元也是 .class,而不是命名空间,不同的“供应商”可以在同一命名空间中提供类。 - Logan Capaldo
这里的“模块”与汇编或.jar没有直接关系,而是指“系统”——一个类、多个类、一个jar文件等。话虽如此,还是要感谢您的精确表述。 - Klaim

3
我注意到在C++中,命名空间很少被使用。 你能否提供相关的实证支持?Boost, Qt,STL等都使用命名空间。

1
@Jpalecek:然而,很多人并没有这样做。所要表达的是Qt广泛使用命名空间。 - Martin York
@Martin York:我在我的Debian系统上执行了nm -DC /usr/lib/libQtCore.so,并查找了不在全局命名空间中的名称。没有发现这样的名称,对于libQtGui.solibQtNetwork.so也是如此。这不是我所谓的“广泛使用”。实际上,Qt API仅包含很少的命名空间,而且这些命名空间通常是次要的领域,还有一些命名空间是实现细节。 - jpalecek
1
@jpalecek:请查看文档:http://cep.xor.aps.anl.gov/software/qt4-x11-4.2.2-browser/d8/d50/namespace_qt.html - Martin York
@Martin York:是的,这是用于常量的一个“单一”命名空间。基本上,在正常使用Qt时,您不会遇到不同的命名空间。这并不构成广泛使用,特别是当全局命名空间仍然被像QTextBoxqSort(请注意Q纯旧前缀半命名空间)这样的名称污染时。 - jpalecek
@Martin York:QT完全在命名空间QT内:这是不正确的。即使您链接的文档也说明了这一点,因此您应该考虑一下您所谓的“愚蠢”。qSort是这样的:http://cep.xor.aps.anl.gov/software/qt4-x11-4.2.2-browser/d4/d35/src_2corelib_2tools_2qalgorithms_8h.html#8f9edc5e7400d5c3d8075f490881dd7d,而不是C qsort。QTextBox应该改为QTextEdit - jpalecek
1
@jpalecek:你试图扭曲“extensive”的含义,这太可笑了:http://encarta.msn.com/dictionary_1861609950/extensive.html QT大部分在命名空间内(http://cep.xor.aps.anl.gov/software/qt4-x11-4.2.2-browser/namespaces.html),因此使用是广泛的(如范围广)。你显然混淆了全局命名空间中的C运行时qsort和QT中不在全局命名空间中的qSort(正如你提供的文档所链接的那样)。QtextEdit似乎在全局命名空间中,但我不确定你如何证明这使得使用不那么广泛。 - Martin York

2

最简单的答案是,当你在Visual Studio(2003及以上版本)中启动程序时,默认会创建命名空间。其他(旧的)IDE可能没有这个功能。

.NET从一开始就推广了它。命名空间并不总是C ++原始实现的一部分,但它在.NET中得到了推广。


1
一个原因是一些流行的编译器(特别是gcc)在很晚才添加了对命名空间的支持,为了更具可移植性,许多项目在没有命名空间的情况下启动。当然,对于一个新项目来说,不使用命名空间会很奇怪。

0

从我在5个不同的地方工作的经验来看,加入之前有2个使用了命名空间。

我猜C++中命名空间没有被广泛使用(应该是因为)语法很笨拙。

例如:我想写这个:

namespace xml::xmpp::core { }

但实际上必须写成这样:

namespace xml { namespace xmpp { namespace core { } } }

而且为了前向声明,我想写成这样:

class xml::parser;

但必须写成这样:

namespace xml { class parser; }

但我可以这样写:

using namespace xml::xmpp::core;

稍微说一下,有人能告诉我为什么类必须以分号结尾,而其他任何东西(函数、命名空间)都不需要吗?


1
那个问题值得单独提出来,因为你可以声明一个变量。类声明有两个可选部分:定义(如果省略,则为前向声明)和变量列表。看一下一些旧的 C 代码,它将每个结构体都定义为 typedef,就会明白我的意思。 - Ben Voigt
命名空间 xml { 类 parser; } 类 xml { 类 parser { ... }; };类 xml::parser; // 这是在预声明哪个 xml::parser? - Logan Capaldo
这就是为什么你需要规则来消除混乱。我会让命名空间优先于类名,所以xml::parser将成为namespace::class。可能会有问题,但我还没有认真思考过。 - graham.reeds

0

命名空间是你在大型项目中的好朋友

看过或没看过-都无所谓。拥抱使用它们的习惯。


0
随着时间的推移,我看到越来越多的C++代码巧妙地使用命名空间。你可能一直在观察C++类编程风格的持续影响... 请注意,我是一名物理学家,我看到的大部分代码都是其他物理学家编写的,所以这可能是我的领域的一个产物。

-1

你没有回答这个问题。 - apocalypse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接