Skip to content

Files

Latest commit

 

History

History
96 lines (78 loc) · 2.86 KB

C++嵌套类.md

File metadata and controls

96 lines (78 loc) · 2.86 KB

C++嵌套类

nested classes

一个class/struct或者union定义在另外一个类中被称作嵌套类。下面定义了一些嵌套类。

阐述

嵌套类的名字存在于一个封闭的类作用范围中,嵌套类的成员函数在检查嵌套类的范围之后,在封闭类的作用于内查找类名称。 和封闭类的其他成员一样,嵌套类可以访问封闭类的任意名称(私有、保护等等),但是它是独立的,不能访问封闭类的this指针。

  • 在嵌套类中仅仅可以定义类型名,静态成员,和枚举类 (until C++11)
  • 在嵌套类中可以使用封闭类的所以有成员,依据usual usage rules
int x,y; // globals
class enclose // enclosing class
{
    // note: private members
    int x;
    static int s;
public:
    struct inner // nested class
    {
        void f(int i)
        {
            x = i; // Error: can't write to non-static enclose::x without instance            
            int a = sizeof x; // Error until C++11,
                              // OK in C++11: operand of sizeof is unevaluated,
                              // this use of the non-static enclose::x is allowed.
            s = i;   // OK: can assign to the static enclose::s            
            ::x = i; // OK: can assign to global x
            y = i;   // OK: can assign to global y
        }
 
        void g(enclose* p, int i)
        {
            p->x = i; // OK: assign to enclose::x
        }
    };
};

在嵌套类中定义友元函数没有访问封闭类的特殊权限,即使从定义在嵌套类中的函数包体中查找,也可以找到封闭类的私有成员。

在命名空间作用域内封闭函数之外定义的成员需要指定嵌套类:

struct enclose
{
    struct inner
    {
        static int x;
        void f(int i);
    };
};
 
int enclose::inner::x = 1;       // definition
void enclose::inner::f(int i) {} // definition

嵌套类也可以前置声明后再定义,和在类做作用域内定义相同:

class enclose
{
    class nested1;    // forward declaration
    class nested2;    // forward declaration
    class nested1 {}; // definition of nested class
};
 
class enclose::nested2 { }; // definition of nested class

嵌套类定义遵循member access规则,私有变量不能在封闭类之外使用,尽管可以操作类对象。

class enclose
{
    struct nested // private member
    {
        void g() {}
    };
public:
    static nested f() { return nested{}; }
};
 
int main()
{
    //enclose::nested n1 = enclose::f(); // error: 'nested' is private
 
    enclose::f().g();       // OK: does not name 'nested'
    auto n2 = enclose::f(); // OK: does not name 'nested'
    n2.g();
}