C++学习之嵌套类和局部类

局部类

在一个函数体内定义的类称为局部类。 局部类中只能使用它的外围作用域中的对象和函数进行联系,因为外围作用域中的变量与该局部类的对象无关。在定义局部类时需要注意:局部类中不能说明静态成员函数,并且所有成员函数都必须定义在类体内。在实践中,局部类是很少使用的。下面是一个局部类的例子。

int a;

void fun()

{

  static int s;

class A

{

  public:

  void init(int i) { s = i; }

};

A m;

  m.init(10);

}

嵌套类理解

在一个类中定义的类称为嵌套类,定义嵌套类的类称为外围类。定义嵌套类的目的在于隐藏类名,减少全局的标识符,从而限制用户能否使用该类建立对象。这样可以提高类的抽象能力,并且强调了两个类 (外围类和嵌套类) 之间的主从关系。

class A

{

public:

    class B 

{   

public:

      …

    private:

      …

    };

    void f();

private:

    int a;

}

其中,类B是一个嵌套类,类A是外围类,类B定义在类A的类体内。

对嵌套类的若干说明:

1、从作用域的角度看,嵌套类被隐藏在外围类之中,该类名只能在外围类中使用。如果在外围类的作用域内使用该类名时,需要加名字限定。

2、从访问权限的角度来看,嵌套类名与它的外围类的对象成员名具有相同的访问权限规则。不能访问嵌套类的对象中的私有成员函数,也不能对外围类的私有部分中的嵌套类建立对象。

3、嵌套类中的成员函数可以在它的类体外定义。

4、嵌套类中说明的成员不是外围类中对象的成员,反之亦然。嵌套类的成员函数对外围类的成员没有访问权,反之亦然。

在分析嵌套类与外围类的成员访问关系时,往往把嵌套类看作非嵌套类来处理。这样,上述的嵌套类可写成如下格式:

class A

{  public:

    void f();

  private:

    int a;

};

class B

{

 public:

   …

private:

  …

};  [ 嵌套类的理解形式 ]

 

5、在嵌套类中说明的友元对外围类的成员没有访问权。

6、如果嵌套类比较复杂,可以只在外围类中对嵌套类进行声明,关于嵌套的详细的内容可在外围类体外的文件域中进行定义。(理解这句话)

嵌套类规则详细分析

1、嵌套类的名字只在外围类可见。

在一个类的内部定义另一个类,我们称之为嵌套类(nested class),或者嵌套类型。之所以引入这样一个嵌套类,往往是因为外围类需要使用嵌套类对象作为底层实现,并且该嵌套类只用于外围类的实现,且同时可以对用户隐藏该底层实现。

       虽然嵌套类在外围类内部定义,但它是一个独立的类,基本上与外围类不相关。它的成员不属于外围类,同样,外围类的成员也不属于该嵌套类。嵌套类的出现只是 告诉外围类有一个这样的类型成员供外围类使用。并且,外围类对嵌套类成员的访问没有任何特权,嵌套类对外围类成员的访问也同样如此,它们都遵循普通类所具有的标号访问控制。

若不在嵌套类内部定义其成员,则其定义只能写到与外围类相同的作用域中,且要用外围类进行限定,不能把定义写在外围类中。例如,嵌套类的静态成员就是这样的一个例子。(如何完成?)

前面说过,之所以使用嵌套类的另一个原因是达到底层实现隐藏的目的。为了实现这种目的,我们需要在另一个头文件中定义该嵌套类,而只在外围类中前向声明这个嵌套类即可。当然,在外围类外面定义这个嵌套类时,应该使用外围类进行限定。使用时,只需要在外围类的实现文件中包含这个头文件即可。

另外,嵌套类可以直接引用外围类的静态成员、类型名和枚举成员,即使这些是private的。一个好的嵌套类设计:嵌套类应该设成私有。嵌套类的成员和方法可以设为public。

嵌套类名字的解析过程

嵌套类定义的名字解析过程:

出现在名字使用点前的嵌套类的声明。

出现在名字使用点前外围类的声明。

嵌套类定义前名字空间域的声明。

嵌套类的成员定义中的名字解析过程:

成员函数局部声明。

嵌套类成员的声明。

外围类成员的声明。

成员函数定义前名字空间域中出现的声明。

参考实例

#include <iostream>

using namespace std;

class A

{

private:

int n;

public:

A(int n)

{

this->n=n;

cout<<"Aconstructor"<<endl;

}

voidshow();

class B

{

public:

B( )

{

cout<<"B constructor"<<endl;

}

voiddisp()

{

cout<<"B disp"<<endl;

}

};

Bb;

};

voidA::show()

{

cout<<n<<endl;

}

void main()

{

A a(1);

a.show();

a.b.disp();

}

class Outter

{

// friend class Inner 加了这行也白搭

(理解为什么)正确写法应该是;

protected:

voidFoo(){}

private:

voidFoo2(){}

public:

voidFoo3(){}

private:

classInner

{

Inner(Outter*pFather)

{

pFather->Foo();// Error, compiler complain !!

pFather->Foo2();//Error, compiler complain !!

pFather->Foo3();//OK !

}

};

};

嵌套的结构(当然包括类)并不能自动获得访问private成员的权限,要获得的话,必须遵守特定的规则:首先声明(不是定义)一个嵌套结构,然后声明它是全局范围使用的一个friend,最后定义这个结构。结构的定义必须与friend声明分开,否则不会把它看做成员。

改成这样,就可以通过编译了

class Outter

{

protected:

voidFoo(){};

private:

voidFoo2(){};

public:

voidFoo3(){};

private:

class Inner; // 声明  (是否可以省略声明?不可以)

friend Inner; // 声明为友元

classInner

{

Inner(Outter*pFather)

{

pFather->Foo();

pFather->Foo2();

pFather->Foo3();

}

};

};

C++学习之嵌套类和局部类的更多相关文章

  1. ZeroC ICE源代码中的那些事 - 嵌套类和局部类

    使用嵌套类(类中定义的类,c++没有静态类)或局部类(在函数或成员方法中定义的类),进行行为模式的委托(委托请求)或异步 . java中嵌套类和局部类隐式完成了你对外部对象(实例)访问的私有堆栈的初始 ...

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

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

  3. Java学习笔记-嵌套类

    嵌套类 嵌套类有两种类别:static and non-static,分别对应为静态嵌套类和内部类. class OuterClass { ... static class StaticNestedC ...

  4. C++ Primer 笔记——嵌套类 局部类

    1.嵌套类是一个独立的类,与外层类基本没什么关系.特别的是,外层类的对象和嵌套类的对象是相互独立的.在嵌套类的对象中不包含任何外层类定义的成员,在外层类的对象中也不包含任何嵌套类定义的成员. 2.嵌套 ...

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

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

  6. 【转】C++之内部类(嵌套类)与外部类及友元

    [转]http://baike.baidu.com/link?url=Md223wQoT5s-3cZ5xRnj1pGmvm310DKAuh-HDrcEdc2l24rwobHrdEc_Mi4Z3BGP0 ...

  7. C/C++基础----特殊工具和技术 (重载new和delete,RTT,限定作用域的枚举类型,类成员指针,嵌套类,局部类,volatile,链接指示 extern “C”)

    重载new和delete 1调用operator new( 或new[])标准库函数分配足够大的.原始的.未命名的内存空间以便存储特定类型的对象 2编译器运行相应地构造函数以构造这些对象,并为其传入初 ...

  8. c++中嵌套类,外部类访问内部类的私有成员变量

    在嵌套类中,内部类可以直接访问外部类的私有成员变量,但是外部类不能直接访问内部类的私有成员变量,必须把外部类声明为内部类的友元类 /********************************** ...

  9. C++ Primer 学习笔记_104_特殊工具与技术 --嵌套类

    特殊工具与技术 --嵌套类 能够在还有一个类内部(与后面所讲述的局部类不同,嵌套类是在类内部)定义一个类,这种类是嵌套类,也称为嵌套类型.嵌套类最经常使用于定义运行类. 嵌套类是独立的类,基本上与它们 ...

随机推荐

  1. Java学习笔记-File类的基本方法

    要渐渐养成写博客的习惯-----> 前段时间看Mars的java中的I/O流没怎么懂,发现I/O流好难啊.今天重新看一遍其他教学,还有书籍,做些笔记,记录下每天的学习生活. File类的一些方法 ...

  2. 关闭浏览器输入框自动补齐 兼容IE,FF,Chrome等主流浏览器

    这篇文章主要介绍了关闭浏览器输入框自动补齐 兼容IE,FF,Chrome等主流浏览器,需要的朋友可以参考下.希望对大家有所帮助   Firefox 和 IE 的浏览器各自实现了input历史记录的功能 ...

  3. response.getWriter().write()与out.print()的区别 (转)

    来自:http://www.cnblogs.com/zhwl/p/3623688.html 1.首先介绍write()和print()方法的区别:  (1).write():仅支持输出字符类型数据,字 ...

  4. 深入理解Java虚拟机:OutOfMemory实战

    在Java虚拟机规范的描述中,除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(下文称OOM)异常的可能,本节将通过若干实例来验证异常发生的场景.并且会初步介绍 ...

  5. interview collect

    1. binary tree inorder traversal 不能用recursive写 (LC原题)2. 比如有个数组F={1,3, 4, 5, 2, 0}, A=3, 那么F[A]=5, F[ ...

  6. <a>标签中 href="/" 和 hideFocus="true"

    一:href="/" 连接到根目录 这是相对路径的根目录表示方法 可以写为 http://class.qq.com/">腾讯精品课 (绝对路径写法) 也可以为 腾讯 ...

  7. [转载]node.js express 4.x 安装指南,没有自动配置环境变量的问题

    前几天express 推出了4.0,得知这个消息,自己尝试了一下,突然发现用以前的文档上的操作出现了各种问题.结果只能去看文档,现在在这个给大家分享下4.0版本的安装. 先说下如果需要用express ...

  8. MYSQL 引擎的情况

    方法 1: show engine innodb status; ------------------------------------------------------------------- ...

  9. 立体像对DEM提取

    版权声明:本教程涉及到的数据仅练习使用,禁止用于商业用途. 目录 1.概述 2.详细操作步骤 第一步:输入立体像对 第二步:定义地面控制点 第三步:定义连接点 第四步:设定DEM提取参数 第五步:输出 ...

  10. javascript将异步校验表单改写为同步表单

    同步表单校验的缺点 响应错误信息时,需要重新加载整个页面(虽然有缓存,客户端仍然需要通过http协议对比每个文件是否有更新,以保持文件最新) 服务器响应错误以后,用户之前所输入的信息全部丢失了,用户需 ...