在一个类的内部定义另一个类或结构体,我们称之为嵌套类(nested class),或者嵌套类型。之所以引入这样一个嵌套类,往往是因为外围类需要使用嵌套类对象作为底层实现,并且该嵌套类只用于外围类的实现,且同时可以对用户隐藏该底层实现。
虽然嵌套类在外围类内部定义,但它是一个独立的类,基本上与外围类不相关。它的成员不属于外围类,同样,外围类的成员也不属于该嵌套类。嵌套类的出现只是告诉外围类有一个这样的类型成员供外围类使用。并且,外围类对嵌套类成员的访问没有任何特权,嵌套类对外围类成员的访问也同样如此,它们都遵循普通类所具有的标号访问控制。
前面说过,之所以使用嵌套类的另一个原因是达到底层实现隐藏的目的。为了实现这种目的,我们需要在另一个头文件中定义该嵌套类,而只在外围类中前向声明这个嵌套类即可。当然,在外围类外面定义这个嵌套类时,应该使用外围类进行限定。使用时,只需要在外围类的实现文件中包含这个头文件即可。
另外,嵌套类可以直接引用外围类的静态成员、类型名和枚举成员,即使这些是private的。
实例如下:
1. #ifndef NESTCLASS_H_
2. #define NESTCLASS_H_
3. class A
4. {
5. public:
6. A();
7. ~A();
8. void operate();
9. private:
10. class B;
11. B* m_b;
12. };
13. #endif
14.
15. #include"nestclass.h"
16. #include<iostream>
17. using namespace std;
18. class A::B
19. {
20. public:
21. B(){}
22. ~B(){}
23. void operate()
24. {
25. cout<<"B operate!"<<endl;
26. }
27. };
28. A::A()
29. {
30. }
31. A::~A()
32. {
33. }
34. void A::operate()
35. {
36. m_b =new B;
37. cout<<"A operate!"<<endl;
38. m_b->operate();
39. }
40. #include"nestclass.h"
41. void main()
42. {
43. A a;
44. a.operate();
45. }
在嵌套类的定义被看到之前我们只能声明嵌套类的指针和引用,如上面在A中定义为B m_b
另:
第一是命名空间的问题,在类里面定义的类或者结构不怕重名,比如说模板类每个类都有个iterator嵌套类,重名也不要紧,更大的好处是还可以利用这个特性写模板函数:
1. template<class T,classFunc>
2. void foreach(T& container,Func f)
3. {
4. for(T::iterator i = container.begin(); i != container.end();++i)
5. {
6. f(*i);
7. }
8. }
第二是可以把类定义成private或者protected,提供访问保护机制。
第三是逻辑上好理解,代码容易懂一些。如果一个类叫ListItem,可能不会想到实现的是ListBox类的Item;而如果变成ListBox::Item,就一目了然了。