外部类与嵌套类的区别
原文网址:http://dingxiuwei666.blog.163.com/blog/static/1615705220106383747539/
局部类
在一个函数体内定义的类称为局部类。局部类中只能使用它的外围作用域中的对象和函数进行联系,因为外围作用域中的变量与该局部类的对象无关。局部类不能被外部所继承。在定义局部类时需要注意:局部类中不能说明静态成员函数,并且所有成员函数都必须定义在类体内。在实践中,局部类是很少使用的。下面是一个局部类的例子。
int a;
void fun()
{
static int s;
class A
{
public:
void init(int i) { s = i; }
};
A m;
m.init(10);
}
局部类的另一个用途是用来实现类型转化,如下代码:
class Interface
{
public:
virtual void Fun() = 0;
};
template <class T, class P>
Interface* MakeAdapter(const T& obj, const P& arg)
{
int x;
class Local : public Interface
{
public:
Local(const T& obj, const P& arg)
: obj_(obj), arg_(arg) {}
virtual void Fun()
{
x = 100;
obj_.Call(arg_);
}
private:
T obj_;
P arg_;
};
return new Local(obj, arg);
}
嵌套类
在一个类中定义的类称为嵌套类,定义嵌套类的类称为外围类。
定义嵌套类的目的在于隐藏类名,减少全局的标识符,从而限制用户能否使用该类建立对象。这样可以提高类的抽象能力,并且强调了两个类(外围类和嵌套类)之间的主从关系。下面是一个嵌套类的例子:
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、如果嵌套类比较复杂,可以只在外围类中对嵌套类进行说明,关于嵌套的详细的内容可在外围类体外的文件域中进行定义。
记得白凤煮的C++中有一句这样的话:C++嵌套类只是语法上的嵌套。然而在实践过程中,却并非如此。
Ex:
class A
{
public:
static int a;
class A1
{
void output()
{
cout<<a<<endl; //instead of A::a;
}
};
};
int A::a;
可见,类 A1 嵌入A后访问A的静态变量不写外围域没有任何问题,从编译的角度看,此时位于A::的作用域内,在符号表中是可以找到a的(注意,a必须为static的)。这一点,与分开写的两个类明显不同
class A
{
private:
int a;
class A1
{
void output(A aObject)
{
cout<<aObject.a<<endl; //instead of A::a;
}
};
};
这段代码在VC中不能编译通过,但在DEV-C++是可以的,也就是不同的编译对于嵌套类是否能访问外围类的私有成员的定义是不一致的。
嵌套类的不同作用域同名问题:
class A
{
public:
static int a;
class A1
{
static int a;
int void output()
{
cout<<a<<endl; //instead of A::a;
}
};
};
int A::a=3;
int A::A1::a=4;
输出内部的a没有问题,如果要访问外部的,使用A::a指明作用域就可以,而且在嵌套类中,可以定义静态的成员。
用类似A::A1::a就可以访问.
先看一下Java的情况
Ex:
//this is a Java class
class A
{
private int c=2;
class A1
{
int c=3;
void output()
{
System.out.println(this.c);
System.out.println(A.this.c);
}
}
}
由定义就可看出,Java的定义是动态定义的,是基于this指针的,因此,嵌套类不只在语法上,在语义上也有隶属关系,外围类的成员,包含私有成员,对于内部类也是可见的。因此内部非Static的类不能有Static成员,且这样的内部类只有在外层的对象建立后才能对建立,所以你可以这么建立对象:
Ex:
A a = new A();
A.A1 aa = a.new A1();
或者:
Ex:
A.A1 aa = new A().new A1(); //使用匿名对象
如果是静态嵌套类
Ex:
//this is a Java class
class A
{
private int c=2; //(1)
static class A1
{
static int c=3;
void output()
{
//System.out.println(this.c); //work well <--> A.A1.c; 这个结果由编译静态成生和动态加载相对地址理论轻松解释
//System.out.println(A.this.c);// (can't work) ,很明显要求外围对象存在,把(1)改成static 的可以通过
System.out.println(c); //work well
}
}
}
对比上面Java的定义,可见C++中的黓认行为和Java中的静态类相似,由此,可以猜出C++中的类是做静态存储的。因此,可以轻松的得出如下语句也是可以的:
Ex:
//C++
A::A1 * a = new A::A1();
因此,也可以得到在 C++ 中 ,内部类也是可以有静态对象的。
转载于:https://www.cnblogs.com/guxuanqing/p/4750107.html
外部类与嵌套类的区别相关推荐
- C++嵌套类的使用及对外部类的访问权限
C++中的嵌套类与Java中的静态内部类类似,而完全不同于非静态内部类(成员内部类). http://www.cnblogs.com/qzhforthelife/archive/2013/07/31/ ...
- java嵌套类与内部类
一.嵌套类(Nested Classes) 使用嵌套类减少了命名冲突,一个内部类可以定义在一个类中,一个方法中甚至一个表达式中. (1)定义 A nested(嵌套) class is any cla ...
- Kotlin学习笔记 第二章 类与对象 第十节 内部类嵌套类
参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...
- Java基础学习第十三讲:Java面向对象---嵌套类
Java面向对象-嵌套类.内部类.匿名类 一.static静态 在<Java编程思想>有这样一段话: "static方法就是没有this的方法.在static方法内部不能调用非静 ...
- 内部类和外部类的详解
一*相关概念: 当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类.内部类也是封装的一种体现. 1.1.内部类 ...
- C++模板类嵌套类内部类局部类的区别
模板类就是将类定义成模板的形式. C++中好像不区分内部类与嵌套类两个名词. 内部类与嵌套类都是指在类中定义类. 局部类是指在函数中定义类. (c++不能在函数中定义函数(python可以).c++在 ...
- java的内部类和外部类_java内部类 和外部类的区别
下面说一说内部类(Inner Class)和静态内部类(Static Nested Class)的区别: 定义在一个类内部的类叫内部类,包含内部类的类称为外部类.内部类可以声明public.prote ...
- ZeroC ICE源代码中的那些事 - 嵌套类和局部类
使用嵌套类(类中定义的类,c++没有静态类)或局部类(在函数或成员方法中定义的类),进行行为模式的委托(委托请求)或异步 . java中嵌套类和局部类隐式完成了你对外部对象(实例)访问的私有堆栈的初始 ...
- 【Java 面向对象】基础、Java程序的内存划分、嵌套类(内部类、静态嵌套类)、局部类、接口的升级问题(默认方法、静态方法)、instanceof
面向对象 对象的内存 复杂对象的内存 对象数组的内存 思考:方法存储在哪里? Java程序的内存划分 this.super 注解(Annotation) 访问控制(Access Control) to ...
- C++ 学习笔记之(19) new、delete表达式、RTTI(运行时类型识别)、枚举、类成员指针、嵌套类、局部类、位域、volatile、extern C
C++ 学习笔记之(19) new.delete表达式.RTTI(运行时类型识别).枚举.类成员指针.嵌套类.局部类.位域.volatile.extern C C++ 学习笔记之(19) new.de ...
最新文章
- 老齐学python的django 源代码_《跟老齐学Python:Django实战》真正的手把手“带”您学习...
- python空值填充_pandas | DataFrame基础运算以及空值填充
- 字符串加括号问题(矩阵乘法组合问题)C++
- linux下利用shell脚本和mysqldump热备份和恢复mysql
- Faster R-CNN 深入理解 改进方法汇总
- scanf的一些小细节
- tableview的顶部有一部分空白区域,并不是Cell的解决方法。
- 多媒体计算机属于哪种教学,多媒体计算机属于哪种教学媒体(???)。
- CreateFile系类异步、并行(同一个串口发送接收)
- java list 在头部添加6_【Java提高十六】集合List接口详解
- excel表格显示无法连接服务器,excel中表格无法连接数据库-EXCEL 连接SQL SERVER数据库显示无法连接...
- TwinCAT3 EL6070-1648授权模块使用
- 字节跳动的 8 轮视频面试流程
- 微信开发者工具封装request请求
- 计算机提示应用程序无法启动,告诉你电脑提示应用程序无法正常启动0x000007b怎么办...
- Python获取图片保存对应的文件夹
- vue+ts的书写规范
- 关于IntelliJ IDEA
- z自建服务器,《守望先锋》将加入自建服务器 自定规则
- PHP 从菜鸟到大咖的踩坑之路
热门文章
- Slideshow Maker for mac(幻灯片制作软件)
- 纯净菜单栏优化管理:Bartender 4 for Mac支持 Monterey
- 苹果Mac上的 Spotlight 扩展小技巧
- Mac键盘被锁的解决方法
- 如何使用Movavi Slideshow Maker创建幻灯片
- java.lang.IllegalArgumentException at java.sql.Date.getHours
- 基于 HTML5 的 3D 工业互联网展示方案
- JavaScript30秒, 从入门到放弃之Array(七)
- Flexbox弹性布局,更优雅的布局
- Neutron Vlan Network 原理- 每天5分钟玩转 OpenStack(92)