关于C++类定义中不能声明该类对象,而Java中可以的原因
相信接触过C++的人,在学习Java的过程当中,会遇到这样一个问题:在Java中常常会在类定义中声明一个该类的对象(例如Person类定义中声明一些叫parents之类的Person对象),但是在C++中,这样的声明是会出现问题的。
例如,在C++中,如下的代码会出错:
class A
{
private:
A a;
};
而在Java当中,这样一段代码可以却可以使用:
class B{
private B b;
}
要理解这样一个问题,首先要知道的是,在Java中,只有基本数据类型和引用数据类型。对于一个类对象,都是使用引用的概念。而Java的引用和C++的引用是不同的,具体内容可以参考这篇博客 https://blog.csdn.net/WaitForFree/article/details/51030013 。
C++中的引用更像是一种“别名”(实质上是个指针常量),例如: Test & test2 = test1 ,test2就可以访问和修改test1内存中存储的内容。当改变test2的值时,改变的是存储在test1内存中的值。
Java中的引用实际上是一种隐藏的指针,例如:Test test2 = test1,这样的语句只是声明了一个名叫test2的引用,并将这个引用指向test1,可以通过test2这个名称访问test1内存中的值。但当改变test2的值时,是将test2这个引用指向一个新的位置,这一点类似于C++的指针。
在上面两段代码中,C++ 的A a是声明了一个A类对象,并为这个对象分配了内存空间,这就造成了无限递归创建对象,不停的分配内存空间,最后堆栈溢出。
而Java中引用数据类型的声明和分配内存是分开的,B b只是声明了B类的一个引用,并没有为它指定一个内存空间,因此不存在无限递归分配空间的问题。
而C++中的指针可以将声明和内存分配分开,因此,如果将上面那段C++代码改成指针形式,则不会出现问题:
class A
{
private:
A *a;
};
当然,如果在类声明中将指针指向new A()的内存空间,则还会出现堆栈溢出的问题。
同理,如果在Java中,为B的对象b new一个内存空间就会出错,此时Java会抛出一个异常。
class B{
private B b = new B();
}
所以,不论是Java还是C++,在实际使用过程中,如果想要在类定义中声明该类的一个对象,则应该使用引用/指针,且不能分配内存,否则在定义中无限递归分配内存会造成堆栈溢出的问题。
关于C++类定义中不能声明该类对象,而Java中可以的原因的更多相关文章
- java中replaceAll反斜杠\ or java中replaceAll 括号[
java中replaceAll反斜杠\ String s=new String("this is a \\"); s.replaceAll("\\",&qu ...
- 用var声明变量,在java中居然有这么多细节,你都了解么?
简介 Java SE 10引入了局部变量的类型推断.早先,所有的局部变量声明都要在左侧声明明确类型. 使用类型推断,一些显式类型可以替换为具有初始化值的局部变量保留类型var,这种作为局部变量类型 的 ...
- 类定义,创建/销毁OC对象
类定义 1 OC类分为2个文件,一个是.h文件,一个是.m文件: 2 .h文件存放类.函数声明: 3 .m文件类的具体实现: 4 类声明使用关键字@interface.@end来声明: 5 类实现使用 ...
- Java中常用来处理时间的三个类:Date、Calendar、SimpleDateFormate,以及Java中的单例设计模式:懒汉式、饿汉式以及静态内部类式
(一)java.util.Date类 1.该类有一个long类型的属性:用来存放时间,是用毫秒数的形式表示,开始的日期是从1970年1月1号 00:00:00. 2.该类的很多方法都已经过时,不 ...
- angularjs中directive声明scope对象的用法
总的来说用法 分三种: >1: scope: false --> 继承父域,实现 双向数据绑定 示例代码 可自测: <!DOCTYPE html> <html lang ...
- JSP中的内置对象和Struts中的Web资源的详解
JSP中的内置对象有如下几种: request :继承于HttpServletRequest, HttpServletRequest继承ServletRequest, 获得的Request对象的方法: ...
- [hadoop] map函数中使用FileSystem对象出现java.lang.NullPointerException的原因及解决办法
问题描述: 在hadoop中处理多个文件,其中每个文件一个map. 我使用的方法为生成一个文件,文件中包含所有要压缩的文件在HDFS上的完整路径.每个map 任务获得一个路径名作为输入. 在eclip ...
- python中print()函数的“,”与java中System.out.print()函数中的“+”
python中的print()函数和java中的System.out.print()函数都有着打印字符串的功能. python中: print("hello,world!") 输出 ...
- 【问题记录】MySQL中时间戳转日期格式和Java中时间戳转日期格式偶尔不一致
背景: MySQL的某个字段存放着一些时间戳格式的时间. 问题描述: Java程序将MySQL中的时间戳字段取出来,在Java程序中转成yyyy-MM-dd HH:mm:ss格式的时候,偶尔会出现转化 ...
随机推荐
- Docker容器入门实践
Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目.它基于 Google 公司推出的 Go 语言实现. 项目后来加入了 Linux 基金会,遵从了 ...
- 在使用Access连接后获取数据--出现此类问题如何解决---未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序解决办法
转载:https://blog.csdn.net/yyzzhc999/article/details/79367114 using System; using System.Collections.G ...
- WindowsServer域用户批量创建方法
@font-face { font-family: "Times New Roman" } @font-face { font-family: "宋体" } @ ...
- 实践丨SpringBoot整合Mybatis-Plus项目存在Mapper时报错
摘要:在SpringBoot运行测试Mybatis-Plus测试的时候报错的问题分析与修复 本文分享自华为云社区<SpringBoot整合MybatisPlus项目存在Mapper时运行报错的问 ...
- 论文解读(MVGRL)Contrastive Multi-View Representation Learning on Graphs
Paper Information 论文标题:Contrastive Multi-View Representation Learning on Graphs论文作者:Kaveh Hassani .A ...
- java 学习笔记(一)
书 head first java 1. 2.加强版的FOR循环 3. 通过super引用父类 4.多态 5.接口和抽象类 接口 6.多线程锁 7.JDBC
- Schema和数据类型优化?
整数TinyInt,SmallInt,MediumInt,Int,BigInt 使用的存储8,16,24,32,64位存储空间.使用Unsigned表示不允许负数,可以使正数的上线提高一倍.实数 Fl ...
- 解释 AOP 模块?
AOP 模块用于发给我们的 Spring 应用做面向切面的开发, 很多支持由 AOP 联 盟提供,这样就确保了 Spring 和其他 AOP 框架的共通性.这个模块将元数据编 程引入 Spring.
- 学习zabbix(六)
实验环境 实验用2到2台机器,实验所用机器系统环境如下,可以看到2台机器的主机名和IP地址 ? 1 2 3 4 5 6 7 8 9 10 [root@linux-node1 ~]# cat /etc/ ...
- SVN回滚步骤