相信接触过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中可以的原因的更多相关文章

  1. java中replaceAll反斜杠\ or java中replaceAll 括号[

    java中replaceAll反斜杠\   String s=new String("this is a \\"); s.replaceAll("\\",&qu ...

  2. 用var声明变量,在java中居然有这么多细节,你都了解么?

    简介 Java SE 10引入了局部变量的类型推断.早先,所有的局部变量声明都要在左侧声明明确类型. 使用类型推断,一些显式类型可以替换为具有初始化值的局部变量保留类型var,这种作为局部变量类型 的 ...

  3. 类定义,创建/销毁OC对象

    类定义 1 OC类分为2个文件,一个是.h文件,一个是.m文件: 2 .h文件存放类.函数声明: 3 .m文件类的具体实现: 4 类声明使用关键字@interface.@end来声明: 5 类实现使用 ...

  4. Java中常用来处理时间的三个类:Date、Calendar、SimpleDateFormate,以及Java中的单例设计模式:懒汉式、饿汉式以及静态内部类式

    (一)java.util.Date类 1.该类有一个long类型的属性:用来存放时间,是用毫秒数的形式表示,开始的日期是从1970年1月1号 00:00:00.    2.该类的很多方法都已经过时,不 ...

  5. angularjs中directive声明scope对象的用法

    总的来说用法 分三种: >1: scope: false  --> 继承父域,实现 双向数据绑定 示例代码 可自测: <!DOCTYPE html> <html lang ...

  6. JSP中的内置对象和Struts中的Web资源的详解

    JSP中的内置对象有如下几种: request :继承于HttpServletRequest, HttpServletRequest继承ServletRequest, 获得的Request对象的方法: ...

  7. [hadoop] map函数中使用FileSystem对象出现java.lang.NullPointerException的原因及解决办法

    问题描述: 在hadoop中处理多个文件,其中每个文件一个map. 我使用的方法为生成一个文件,文件中包含所有要压缩的文件在HDFS上的完整路径.每个map 任务获得一个路径名作为输入. 在eclip ...

  8. python中print()函数的“,”与java中System.out.print()函数中的“+”

    python中的print()函数和java中的System.out.print()函数都有着打印字符串的功能. python中: print("hello,world!") 输出 ...

  9. 【问题记录】MySQL中时间戳转日期格式和Java中时间戳转日期格式偶尔不一致

    背景: MySQL的某个字段存放着一些时间戳格式的时间. 问题描述: Java程序将MySQL中的时间戳字段取出来,在Java程序中转成yyyy-MM-dd HH:mm:ss格式的时候,偶尔会出现转化 ...

随机推荐

  1. uoj310【UNR #2】黎明前的巧克力(FWT)

    uoj310[UNR #2]黎明前的巧克力(FWT) uoj 题解时间 对非零项极少的FWT的优化. 首先有个十分好想的DP: $ f[i][j] $ 表示考虑了前 $ i $ 个且异或和为 $ j ...

  2. linux安装maven环境

    linux安装maven环境 一. 下载压缩包: 官网地址: http://maven.apache.org/download.cgi 或者百度网盘链接:https://pan.baidu.com/s ...

  3. 利用 ps 怎么显示所有的进程? 怎么利用 ps 查看指定进程的信息?

    ps -ef (system v 输出)ps -aux bsd 格式输出ps -ef | grep pid

  4. 三、MyCat主要配置介绍

    一.配置文件 1.server.xml Mycat的配置文件,设置账号.参数等2.schema.xml Mycat对应的物理数据库和数据库表的配置3.rule.xml Mycat分片(分库分表)规则 ...

  5. volatile 类型变量提供什么保证?

    volatile 变量提供顺序和可见性保证,例如,JVM 或者 JIT 为了获得更好的性能 会对语句重排序,但是 volatile 类型变量即使在没有同步块的情况下赋值也不会 与其他语句重排序. vo ...

  6. java模板设计

  7. ROS环境变量的设置

    一.前言(大神可以直接跳过) 本博客主要就是为了介绍ROS中环境变量的设置过程,还不是很了解ROS的可以去看一下我的博客,ROS简介-从零开始讲解ROS(适合超零基础阅读) ROS为什么需要设置环境变 ...

  8. 接口combine

    需求描述 进行复杂项目开发时,服务端(数据接口实现端)会把接口拆分的比较细粒度,以方便在更多地方复用.而拆分后的接口在前端进行组合请求时,通常会出现一个区块要请求5.6个接口甚至更多接口请求才能拿到想 ...

  9. [翻译]Service workers:PWA背后的英雄

    原文地址:https://medium.freecodecamp.org/service-workers-the-little-heroes-behind-progressive-web-apps-4 ...

  10. mysql8.0.13本地安装忘记密码解决办法

    之前一直用图形化界面,加上考研期间也没动,竟然把我的数据库密码给忘了,无地自容....... 找了找教程,问题如下: MySQL从低版本向高版本迭代变化的过程,越来越严谨的安全性是其一大特点之一,在版 ...