C++ 嵌套类使用(一)
一、嵌套类
在一个类的内部定义另一个类,我们称之为嵌套类(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++ 嵌套类使用(一)的更多相关文章
- spring 笔记1: mvn 中Controller方法的参数不能是嵌套类(内部类)。
最近做spring开发,个人认为,Controller和客户端js通讯时传递的参数类 只使用某几个方法,为了减少对其他功能的影响,想把参数类定义为Controller类的 嵌套类(内部类).但是实践发 ...
- JAVA 嵌套类和内部类
一.什么是嵌套类及内部类? 可以在一个类的内部定义另一个类,这种类称为嵌套类(nested classes),它有两种类型: 静态嵌套类和非静态嵌套类.静态嵌套类使用很少,最重要的是非静态嵌套类, ...
- 学习django之构建Web是Meta嵌套类的几处使用
Django中meta嵌套类的使用 1.模型中使用嵌套类 在定义抽象模型时如: class Meta : abstract=true 用来指明你创建的模型是一个抽象基础类的模型继承. 2.在一个对象对 ...
- java嵌套类
java有四种嵌套类: 静态内部类,成员内部类,局部内部类,匿名内部类 1)静态内部类: (1)类的申明加上staitc关键字.一般用public修饰 (2)只能访问外部类的静态变量和静态方法.不能访 ...
- scala 学习笔记(04) OOP(上)主从构造器/私有属性/伴生对象(单例静态类)/apply方法/嵌套类
一.主从构造器 java中构造函数没有主.从之分,只有构造器重载,但在scala中,每个类都有一个主构造器,在定义class时,如果啥也没写,默认有一个xxx()的主构造器 class Person ...
- c++嵌套类-内存分配
首先看下列代码:int main(){ double *p; printf("sizeof(int):%d\nsizeof(double):%d\nsizeof(ptr):%d\ ...
- Java内部类、静态嵌套类、局部内部类、匿名内部类
Nested classes are further divided into two types: static nested classes: If the nested class is sta ...
- java 嵌套类 简记
嵌套类包括:1)静态嵌套类 (static 修饰符) 2)非静态嵌套类(又叫内部类) 其中内部类又可分为三种: 其一.在一个类(外部类)中直接定义的内部类: 其二.在一个方法(外部类的方法)中定义的 ...
- Java7编程 高级进阶学习笔记--嵌套类
定义: 在一个类中定义的类叫做嵌套类. 作用: 1.允许对相关类进行逻辑分组 2.增强了代码的封装性 3.使代码具有更强的可读性和维护性 使用方式: package com.cmz.baseTest; ...
- 【转】C#类的分类(静态类、实例类、嵌套类、结构、简单的抽象类、简单的密封类)
静态类 -------------------------------------------------------------------------------- 静态类就是在class关键字前 ...
随机推荐
- 使用visual studio 2015调用阿里云oss .net sdk 2.2的putobject接口抛出outofmemory异常
问题描述: 使用阿里云oss .net sdk 2.2版本,使用putobject接口上传文件时,抛出outofmemory异常. 原因分析: 上传时,用于准备上传的数据缓冲区内存分配失败.与应用软件 ...
- Linux/centos/redhat下各种压缩解压缩方式详解
1.zip命令 zip -r myfile.zip ./* 将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件. 2.unzip unzip -o -d ...
- 第二篇、为UITableViewCell 高度自适应加速 缓存cell的高度
通过NSCache缓存已经算好的行高 @interface ZHCellHeightCalculator : NSObject //系统计算高度后缓存进cache -(void)setHeight:( ...
- Electron(一)--初步了解并动手HelloWorld
现在需要做一个桌面应用,心里有点不甘,因为想做出一个简单的客户端,你要么使用Java的Swing编程,要么会使用MFC等等,这样学习的代价太高,也不便维护,于是了解了一下Electron,Electr ...
- GDI+
1, 编译error的话一般是却 #include <comdef.h>#include <Windows.h> Windows.h内会包含Windows.h,但是因为在std ...
- emacs_1
--> 正在处理依赖关系 perl(VMS::Filespec),它被软件包 perl-PathTools-3.2701-1.el5.rf.x86_64 需要---> 软件包 perl-p ...
- 'WinMain' : function cannot be overloaded
Create a MFC Application (UNICODE), paste following code in one of your cpp file. int APIENTRY WinMa ...
- C++多线程技术windows常用方法
随着计算机CPU计算能力快速提高,计算机的处理性能和并行性能力也大大提升.那么,一味使用运行时标准库的C++语言也应该开始支持多线程技术.今天,我为大家带来了C++在windows平台下的常用多线程方 ...
- Sublime Text 破解
引言 放假三天,呆家里把win7换成了win8.1,接着玩起了hyperv,试着装了个windows xp虚拟机,体验很不错.不过对linux系统的支持不怎么样,装了个ubuntu,体验相当差!闲着无 ...
- jQuery获取同级元素
next()相邻下一个同级元素 prev()相邻上一个同级元素 siblings()所有同级元素 $("#id").next(); $("#id").prev( ...