【C++基础】第一百一十二课:[特殊工具与技术]局部类

局部类

Posted by x-jeff on September 17, 2024

【C++基础】系列博客为参考《C++ Primer中文版(第5版)》C++11标准)一书,自己所做的读书笔记。
本文为原创文章,未经本人允许,禁止转载。转载请注明出处。

1.局部类

类可以定义在某个函数的内部,我们称这样的类为局部类(local class)。局部类定义的类型只在定义它的作用域内可见。和嵌套类不同,局部类的成员受到严格限制。

局部类的所有成员(包括函数在内)都必须完整定义在类的内部。因此,局部类的作用与嵌套类相比相差很远。

在局部类中不允许声明静态数据成员。

1.1.局部类不能使用函数作用域中的变量

局部类对其外层作用域中名字的访问权限受到很多限制,局部类只能访问外层作用域定义的类型名、静态变量以及枚举成员。如果局部类定义在某个函数内部,则该函数的普通局部变量不能被该局部类使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int a, val;
void foo(int val)
{
    static int si;
    enum Loc { a = 1024, b };
    //Bar是foo的局部类
    struct Bar {
        Loc locVal; //正确:使用一个局部类型名
        int barVal;

        void fooBar(Loc l = a) //正确:默认实参是Loc::a
        {
            barVal = val; //错误:val是foo的局部变量
            barVal = ::val; //正确:使用一个全局对象
            barVal = si; //正确:使用一个静态局部对象
            locVal = b; //正确:使用一个枚举成员
        }
    };
    //...
}

1.2.常规的访问保护规则对局部类同样适用

外层函数对局部类的私有成员没有任何访问特权。当然,局部类可以将外层函数声明为友元;或者更常见的情况是局部类将其成员声明成公有的。

1.3.局部类中的名字查找

局部类内部的名字查找次序与其他类相似。在声明类的成员时,必须先确保用到的名字位于作用域中,然后再使用该名字。定义成员时用到的名字可以出现在类的任意位置。如果某个名字不是局部类的成员,则继续在外层函数作用域中查找;如果还没有找到,则在外层函数所在的作用域中查找。

1.4.嵌套的局部类

可以在局部类的内部再嵌套一个类。此时,嵌套类的定义可以出现在局部类之外。不过,嵌套类必须定义在与局部类相同的作用域中。

1
2
3
4
5
6
7
8
9
10
11
12
void foo()
{
    class Bar {
    public:
        //...
        class Nested; //声明Nested类
    };
    //定义Nested类
    class Bar::Nested {
        //...
    };
}

局部类内的嵌套类也是一个局部类,必须遵循局部类的各种规定。嵌套类的所有成员都必须定义在嵌套类内部。