一、嵌套类

在一个类的内部定义另一个类,我们称之为嵌套类(nested class),或者嵌套类型。之所以引入这样一个嵌套类,往往是因为外围类需要使用嵌套类对象作为底层实现,并且该嵌套类只用于外围类的实现,且同时可以对用户隐藏该底层实现。
 
 
   虽然嵌套类在外围类内部定义,但它是一个独立的类,基本上与外围类不相关。它的成员不属于外围类,同样,外围类的成员也不属于该嵌套类。嵌套类的出现只是告诉外围类有一个这样的类型成员供外围类使用。并且,外围类对嵌套类成员的访问没有任何特权,嵌套类对外围类成员的访问也同样如此,它们都遵循普通类所具有的标号访问控制。
 
 
 
   若不在嵌套类内部定义其成员,则其定义只能写到与外围类相同的作用域中,且要用外围类进行限定,不能把定义写在外围类中。例如,嵌套类的静态成员就是这样的一个例子。
 
 
   前面说过,之所以使用嵌套类的另一个原因是达到底层实现隐藏的目的。为了实现这种目的,我们需要在另一个头文件中定义该嵌套类,而只在外围类中前向声明这个嵌套类即可。当然,在外围类外面定义这个嵌套类时,应该使用外围类进行限定。使用时,只需要在外围类的实现文件中包含这个头文件即可。

另外,嵌套类可以直接引用外围类的静态成员、类型名和枚举成员(假定这些成员是公有的)。类型名是一个typedef名字、枚举类型名、或是一个类名。

实例如下:

#ifndef NESTCLASS_H_ 
#define NESTCLASS_H_

class A
{
public:
     A();
     ~A();
 
     void operate();
private:
     class B;
     B* m_b;
};
 
#endif

#include "nestclass.h" 
#include  
using namespace std;
 
class A::B
{
public:
     B(){}
     ~B(){}
 
     void operate()
     {
         cout<<"B operate!"<<endl;
     }
};
 
A::A()
{
 
}
 
A::~A()
{
 
}
 
void A::operate()
{
    m_b = new B;
    cout<<"A operate!"<<endl;
    m_b->operate();
}

#include "nestclass.h"

void main()
{
     A a;
     a.operate();
}
 
        在嵌套类的定义被看到之前我们只能声明嵌套类的指针和引用,如上面在A中定义为B m_b而不是B* m_b将会引发一个编译错误。

关于C++嵌套类的详细用法请参考《C++ Primer 第三版》P551。

二、局部类

类也可以定义在函数体内 这样的类被称为局部类(local class), 局部类只在定义它的局部域内可见,与嵌套类不同的是,在定义该类的局部域外没有语法能够引用局部类的成员, 因此,局部类的成员函数必须被定义在类定义中,在实际中,这就把局部类的成员函数的复杂性限制在几行代码中,否则,对读者来说,代码将变得很难理解。

因为没有语法能够在名字空间域内定义局部类的成员 ,所以也不允许局部类声明静态数据成员。

在局部类中嵌套的类可以在其类定义之外被定义,但是,该定义必须出现在包含外围局部类定义的局部域内。在局部域定义中的嵌套类的名字必须由其外围类名限定修饰,在外围类中,该嵌套类的声明不能被省略。例如:

void foo( int val ) 

class Bar { 
public: 
  int barVal; 
  class nested; // 嵌套类的声明是必需的 
}; 
 
// 嵌套类定义 
class Bar::nested { 
  // ... 
}; 
}

外围函数没有特权访问局部类的私有成员,当然,这可以通过使外围函数成为局部类的友元来实现。

同嵌套类一样,局部类可以访问的外围域中的名字也是有限的,局部类只能访问在外围局部域中定义的类型名、静态变量以及枚举值,例如:

int a, val; 
 
void foo( int val ) 

static int si; 
enum Loc { a = 1024, b }; 
 
class Bar { 
public: 
  Loc locVal; // ok; 
  int barVal; 
  void fooBar( Loc l = a ) { // ok: Loc::a 
   barVal = val; // 错误: 局部对象 
   barVal = ::val; // OK: 全局对象 
   barVal = si; // ok: 静态局部对象 
   locVal = b; // ok: 枚举值 
  } 
}; 
// ... 
}

在局部类体内,不包括成员函数定义中的 的名字解析过程是,在外围域中查找出现在局部类定义之前的声明,在局部类的成员函数体内的名字的解析过程是:在查找外围域之前 ,首先直找该类的完整域 。

还是一样,如果先找到的声明使该名字的用法无效,则不考虑其他声明,即使在fooBar() 中使用 val 是错的,编译器也不会找到全局变量val ,除非用全局域解析操作符限定修饰 val,如 ::val 。

C++ 嵌套类使用(一)的更多相关文章

  1. spring 笔记1: mvn 中Controller方法的参数不能是嵌套类(内部类)。

    最近做spring开发,个人认为,Controller和客户端js通讯时传递的参数类 只使用某几个方法,为了减少对其他功能的影响,想把参数类定义为Controller类的 嵌套类(内部类).但是实践发 ...

  2. JAVA 嵌套类和内部类

    一.什么是嵌套类及内部类?  可以在一个类的内部定义另一个类,这种类称为嵌套类(nested classes),它有两种类型:  静态嵌套类和非静态嵌套类.静态嵌套类使用很少,最重要的是非静态嵌套类, ...

  3. 学习django之构建Web是Meta嵌套类的几处使用

    Django中meta嵌套类的使用 1.模型中使用嵌套类 在定义抽象模型时如: class Meta : abstract=true 用来指明你创建的模型是一个抽象基础类的模型继承. 2.在一个对象对 ...

  4. java嵌套类

    java有四种嵌套类: 静态内部类,成员内部类,局部内部类,匿名内部类 1)静态内部类: (1)类的申明加上staitc关键字.一般用public修饰 (2)只能访问外部类的静态变量和静态方法.不能访 ...

  5. scala 学习笔记(04) OOP(上)主从构造器/私有属性/伴生对象(单例静态类)/apply方法/嵌套类

    一.主从构造器 java中构造函数没有主.从之分,只有构造器重载,但在scala中,每个类都有一个主构造器,在定义class时,如果啥也没写,默认有一个xxx()的主构造器 class Person ...

  6. c++嵌套类-内存分配

    首先看下列代码:int main(){    double *p;    printf("sizeof(int):%d\nsizeof(double):%d\nsizeof(ptr):%d\ ...

  7. Java内部类、静态嵌套类、局部内部类、匿名内部类

    Nested classes are further divided into two types: static nested classes: If the nested class is sta ...

  8. java 嵌套类 简记

    嵌套类包括:1)静态嵌套类  (static 修饰符) 2)非静态嵌套类(又叫内部类) 其中内部类又可分为三种: 其一.在一个类(外部类)中直接定义的内部类: 其二.在一个方法(外部类的方法)中定义的 ...

  9. Java7编程 高级进阶学习笔记--嵌套类

    定义: 在一个类中定义的类叫做嵌套类. 作用: 1.允许对相关类进行逻辑分组 2.增强了代码的封装性 3.使代码具有更强的可读性和维护性 使用方式: package com.cmz.baseTest; ...

  10. 【转】C#类的分类(静态类、实例类、嵌套类、结构、简单的抽象类、简单的密封类)

    静态类 -------------------------------------------------------------------------------- 静态类就是在class关键字前 ...

随机推荐

  1. 操作Excel导入的问题(转)

    当Excel导入成为需要时,之前的导出Excel为html方式的方法就受阻了,于是,需要开始新的百度与google来解决问题. 前提为OLEDB+Excel. 根据需求,多数是对于表的数据的导入.于是 ...

  2. UML建模文章总结

    一.为什么要学习UML UML是Unified Modeling Language(统一建模语言)的简称.UML是对软件密集型系统中的制品进行可视化.详述.构造和文档化的语言.制品{Artifact} ...

  3. Spring boot 1.3.5 RELEASE 官方文档中文翻译--Part2:新手入门

    Part II. 新手入门 如果你刚刚开始学习Spring boot或"普通"的Spring,这部分非常适合你!在这里,我们回答了最基础的"什么是?".&quo ...

  4. (UVALive 7261)Xiongnu's Land 二分

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  5. memset与NULL区别

    memset与NULL区别 NULL与0 的区别 为什么强调一个malloc对应一个free 在一个结构体malloc,然后free,但是她的成员变量的malloc并没有free,还需要特别的free ...

  6. JDK中工具类的使用

    JDK中内置了很多常用的工具类,且多以“s”结尾,如:集合工具类Collections,数组工具类Arrays,对象工具类Objects,文件工具类Files,路径工具类Paths,数学工具类Math ...

  7. nutch安装配置

    http://nlp.solutions.asia/?p=180 http://www.promenade.me/archives/146 环境 ubuntu 12.04 sql建表 CREATE D ...

  8. apache 设置禁止访问某些文件或目录

    [apache配置禁止访问]1. 禁止访问某些文件/目录增加Files选项来控制,比如要不允许访问 .inc 扩展名的文件,保护php类库:<Files ~ "\.inc$" ...

  9. Qt5.4生成安装包过程

    所需工具: 1.  HM NIS Edit 2.  windeployqt.exe 第一个工具需要自己去网上下载,第二个工具可以在qt安装目录下找到:D:\qtopengl\5.4\mingw491_ ...

  10. 构造函数继承关键apply call

    主要我是要解决一下几个问题: 1.        apply和call的区别在哪里 2.        apply的其他巧妙用法(一般在什么情况下可以使用apply) 我首先从网上查到关于apply和 ...