未命名的命名空间与私有变量

Unnamed namespaces vs private variables

本文关键字:变量 命名空间 未命名      更新时间:2023-10-16

我一直在阅读这里的其他问题,有些地方让我感到困惑,希望能解释清楚。我确信这是一件简单的事情,但它在暗指我。

因此,在C++中,我们有只能在类中查看的私有变量:

class MyClass
{
    private:
        int i;
};

但我们也可以有未命名的名称空间:

namespace
{
    int i;
}

两者似乎都是类的私有,但在第二种情况下,您无法从头文件中看到它们的存在。从阅读其他问题来看,函数似乎有所不同,因为你不能将类对象传递给它们?但我不确定变量之间的区别是什么。

第二种方法是否有缺点,这意味着你仍然应该使用私有变量?

它们不一样。

匿名命名空间中的整数i将由MyClass的所有实例共享。

MyClass中的私有整数i对于类的每个实例化都是唯一的。

使用private的等效方法是使i静态:

//.h
class MyClass
{
    private:
        static int i;
};

并实例化一个单独的共享i,如下所示:

//.cpp
int MyClass::i = 0;

两人似乎都是全班同学的私人。。。

不,只有第一个对全班是私人的。它是一个非静态成员变量;在类类型的每个对象中都实例化一个。

第二个根本不在一个班级里;它具有静态存储持续时间,因此为整个程序实例化一个。任何访问它的东西都与访问它的其他东西访问相同的变量。由于处于未命名的命名空间中,它只能在定义它的翻译单元(即源文件)中访问;但是任何代码都可以访问它,而不仅仅是一个特定的类。

第二种方法是否有缺点,这意味着你仍然应该使用私有变量?

如果您希望在每个类对象中都有一个变量的副本,那么您需要它是一个非静态成员。

如果您想在所有对象之间共享它,那么您可以决定是将它作为静态成员,还是将它放在类的实现文件中的命名空间中。我经常使用后者来简化类定义。缺点是,访问不仅限于类,还限于该文件中的任何其他内容,并且您不能从任何您可能想放在头中的代码中访问它。

命名空间与对象/类无关。特别是,如果有两个对象,每个对象都有自己的私有变量副本。

它们是完全不同的概念。私有数据成员仅对类可见,在非静态情况下,每个类实例都拥有其中一个。匿名命名空间允许您使代码仅对同一文件中的其他代码可用。因此,在单个int变量的情况下,与匿名命名空间在同一位置定义的所有代码都会看到相同的单个变量。