Java和C++通过new创建的对象有何区别?
作者:Wray Zheng 发布时间:2022-02-07 10:06:10
前言
本文我们不去谈int、float、char等基本数据类型,而是用一般的类来说明。因为Java中可以直接通过 int varName 的方式来定义和使用一个基本类型的变量,但对于其它一般类型的对象,必须使用 new 来创建。
因此,为了更一般性地分析,体现两种语言创建对象的差异,我们用自定义的类 Student 进行说明,以下内容均针对一般的类而言。
Java
在 Java 中,我们可以通过如下方式定义变量:
Student s; //定义标识符s,没有实际空间
Student s = new Student(); //定义s,并绑定到新创建的对象
JVM在进行内存管理时,首先会在栈中给dog分配一个空间,当new Dog();后会在堆中开辟对象的实际空间,然后将dog指向堆中的空间,这样我们就可以方法对象的成员变量了。
图3 Java创建对象方式的内存分配
c++
在C++中,变量也可以同上来定义,但含义不同:
Student s; //定义标识符s,并在栈中申请空间
Student* s = new Student(); //定义s,并在堆中申请空间,过后需手动释放内存
这两种方式在C++中都能完成对象的创建,但是在内存中的处理却完全不同。
对于第一种方式而言,dog是被存储在栈中的,占用的大小是Dog类中成员变量占用内存的和,此处不包括成员方法,因为成员方法是存放在公共存储区以便所有该类的对象都可以访问的。
图1 C++创建对象方式1的内存分配
对于第二种方式则不同,该方式使用了指针,在定义*p时在栈中开辟一个4字节的空间,new Dog()时在堆中开辟一块空间,然后将该空间的首地址赋值给*p,这样,通过*p就可以找到对象在堆中的任何成员方法了。
图2 C++创建对象方式2的内存分配
区别总结
两种语言里都含有 new 操作符,但它们的含义大不相同,这与它俩的变量管理方式有关。
在 Java 中,只有当你使用 new 操作符时,才会真正在内存中申请一块空间,创建一个新对象,并将该对象绑定到你所定义的变量名上。其它情况下,要么是将已有对象绑定到某个变量名上,要么就是定义的变量名是个空引用,没有绑定任何对象。
也就是说,定义变量名只是创建了一个新的标识符,跟创建对象没有关系,创建对象必须通过 new 来完成,只有创建对象时才会申请内存空间。
但在 C++ 中,当你定义了一个变量 s 时,即使你没有给它赋值,也意味着你不但创建了一个新的标识符,同时还在栈中申请了对应的内存空间。
因此,C++ 中定义的变量名不仅仅是个标识符,还自动关联着栈中的一块内存空间。
而 C++ 中的 new 操作符表示的是在堆中申请内存,因为栈中的内存在运行时期大小是固定且有限的,因此需要动态内存分配的时候就需要用 new 来实现。这类似于 C 里面的 malloc 函数,只不过 new 操作符还封装了其它的操作。
总结而言,Java 中的变量名仅仅是一个用于引用内存中实际对象的标识符,如果你没给它关联对象,它就为空引用。而 C++ 中的变量名(非指针类型),虽然也是标识符,但却始终关联着实际的内存空间,当我们看到一个变量(非指针类型)时,就知道它代表着一块实际的内存空间。
来源:http://www.codebelief.com/article/2017/11/difference-between-java-and-cpp-using-new-operator-to-create-an-object/


猜你喜欢
- 前言:在日常开发中经常会遇到字符串匹配问题,我们就来学习使用Java中的一些方便快捷的方法来解决这个问题吧使用String类Java自带的字
- 前言Java的StringUtil.isEmpty(str)和"".equals(str)都是用来判断字符串是否为空的方
- 当setCanceledOnTouchOutside(true),点击阴影处,dialog dismiss时键盘不消失的问题。如图一开始觉得
- Java多线程下载网图案例此案例依赖——文件操作工具类(FileUtils)使用 apache 的commons-io包下的FileUtil
- 一.搭建1.前端npm installnpm run serve2.后端老生常谈的配置,修改mysql与redis即可。二.业务功能介绍功能
- 第一步。根据卷标,CPU序列号,生成机器码// 取得设备硬盘的卷标号
- 简介相信大家有配置过多数据源,或者即将配置多数据的朋友们,会发现网上大概有以下几种方案:1. 使用 AOP 切片进行动态数据源切换2. 使用
- Android 完全退出的实例详解首先,在基类BaseActivity里,注册RxBus监听:public class BaseActivi
- 1.SpringBoot AOP功能1.1 LTW与不同的切面织入时机AOP——面向切面编程,通过为
- 对于Android View的测量,我们一句话总结为:
- Java是一种强类型, 许多流行的编程语言都已经支持局部变量类型推断,如js,Python,C++等JDK10 可以使用var作为局部变量类
- C#关于颜色值的表示:常用的颜色值表示方式有两种,一种是10进制的RGB值表示,如(0,113,255),三个值分别表示(红,绿,蓝);一种
- 在上篇博客初识Spring Boot框架中我们初步见识了SpringBoot的方便之处,很多小伙伴可能也会好奇这个spring Boot是怎
- 这篇文章主要介绍了java通过Jsoup爬取网页过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 本文实例讲述了Java枚举类用法。分享给大家供大家参考。具体如下:package com.school.stereotype; /** *
- Volley简介我们平时在开发Android应用的时候不可避免地都需要用到网络技术,而多数情况下应用程序都会使用HTTP协议来发
- Android中实现全屏、无标题栏的两种办法,另附Android系统自带样式的解释实现全屏无标题栏:1.在xml文件中进行配置 Androi
- 前言传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop、事物,这么做有两个缺点:1、如果所有的内容都配置在.xml
- 本文主要介绍了Java实现雪花算法(snowflake),分享给大家,具体如下:简单描述最高位是符号位,始终为0,不可用。41位的时间序列,
- 标识符Java 对各种变量、方法和类等要素命名时使用的字符序列称为标识符技巧:凡是自己可以起名字的地方都叫标识符定义合法标识符规则:由26个