类与命名空间作用域

Class vs Namespace scope

本文关键字:作用域 命名空间      更新时间:2023-10-16

好的,所以我正在阅读Bjarne Stroustrup的《C++之旅》这本书,它的类和命名空间范围定义如下:

作用域:如果名称是在类中定义的,则称为成员名称(或类成员名称),位于任何函数或枚举类之外。其范围从其附文声明的开头{延伸到该声明的结尾。

命名空间

作用域:如果名称在任何函数、、类或枚举类之外的命名空间中定义,则称为命名空间成员名称。它的范围从声明点延伸到其命名空间的末尾。

坦率地说,我无法理解其中的区别。如果有人能为初学者用更简单的术语或更详细的术语来解释这一点,那将不胜感激。

"命名空间"到底是什么意思?类作用域是否作为类的成员变量,命名空间作用域是否作为任何类之外的全局变量?我的解释正确吗?

"命名空间"到底是什么意思?

假设我写这个:

namespace ns1
{
    class foo{}
}
namespace ns2
{
    class foo{}
}

现在,即使两个类的名称相同,编译器也会将它们视为: ns1::foons2::foo即它们是不同的阶级。

类作用域

和命名空间作用域:

namespace ns1{
    int a; // a has existence from here
    class foo{
        int b; // b has existence from here
    }          // b has existence upto here
}  //a has existence upto here

类是一组相互关联的变量和过程。他们被班级绑在一起。例:

class Human {
public:
    int age;
    string name;
    void GrowOlder() { age += 1; }
};

该类定义中的所有项都在类范围内。为了使用该类,您可以执行以下操作:

Human grendan;
grenden.name = "grenden";
grenden.GrowOlder();

此示例中使用了"Human"类的"name"和"GrowOlder"成员。如果你只是写

name = "grenden"

如果您当前不在"人类"类范围之外,这将是一个错误。

当许多库或应用程序尝试相互交互时,就会出现问题。每个类可能都有自己的字符串库、自己的向量数学库等,因此可能存在重复的类名。命名空间是此问题的解决方案。您可以将类放在命名空间中,以便更好地限定它。

namespace foo
{
    class Human {
    public:
        int age;
        string name;
        void GrowOlder() { age += 1; }
    };
};

现在,"Human"类位于"foo"命名空间范围内。如果你在命名空间之外工作,"Human"不再有任何意义。现在为了使用"Human"类,代码如下所示:

foo::Human grendan;
grenden.name = "grenden";
grenden.GrowOlder();

注意额外的"foo::"。这告诉编译器查看"foo"命名空间范围以查找"Human"类。

通常,如果您在类的某个过程中,则处于类范围内。

如果你在命名空间 {} 块内,或者代码文件中更高位置有"using namespace foo;"语句,则你位于命名空间范围内。

例:

void test()
{
    std::string example = "testest";
}

或者,使用命名空间:

using namespace std;
void test()
{
    string example = "testest";
}

能想到的class/structnamespace之间的差异:

  1. class定义不能多次使用。namespace可以多次用于扩展其内容。

    class A { int a; };
    class A { int b; };   // This is not allowed.
                          // You can extend the class by creating
                          // a sub-class and adding new members to
                          // the derived class but you cannot add
                          // members to a class by defining it again.
    
    namespace A { int a; }
    namespace A { int b; }   // Perfectly fine.
                             // b is an additional member of the namespace.
    
  2. 您可以创建class的对象。不能创建namespace的对象。class有存储要求,namespace没有。