C++用new创建对象和不用new创建对象的区别解析

在C++用new创建对象和不用new创建对象是有区别的,不知你是否清楚的了解它们到底有什么样的区别呢?下面小编就用示例来告诉大家吧,需要的朋友可以过来参考下

我们都知道C++中有三种创建对象的方法,如下:

 1 #include <iostream>
 2 using namespace std;
 3 class A
 4 {
 5 private:
 6     int n;
 7 public:
 8     A(int m):n(m)
 9     {
10     }
11     ~A(){}
12 };
13 int main()
14 {
15     A a(1);  //栈中分配
16     A b = A(1);  //栈中分配
17     A* c = new A(1);  //堆中分配
18   delete c;
19     return 0;
20 }

第一种和第二种没什么区别,一个隐式调用,一个显式调用,两者都是在进程虚拟地址空间中的栈中分配内存,而第三种使用了new,在堆中分配了内存,而栈中内存的分配和释放是由系统管理,而堆中内存的分配和释放必须由程序员手动释放,所以这就产生一个问题是把对象放在栈中还是放在堆中的问题,这个问题又和堆和栈本身的区别有关:

这里面有几个问题:
1.堆和栈最大可分配的内存的大小
2.堆和栈的内存管理方式
3.堆和栈的分配效率

首先针对第一个问题,一般来说对于一个进程栈的大小远远小于堆的大小,在linux中,你可以使用ulimit -s (单位kb)来查看一个进程栈的最大可分配大小,一般来说不超过8M,有的甚至不超过2M,不过这个可以设置,而对于堆你会发现,针对一个进程堆的最大可分配的大小在G的数量级上,不同系统可能不一样,比如32位系统最大不超过2G,而64为系统最大不超过4G,所以当你需要一个分配的大小的内存时,请用new,即用堆。

其次针对第二个问题,栈是系统数据结构,对于进程/线程是唯一的,它的分配与释放由操作系统来维护,不需要开发者来管理。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时,这些存储单元会被自动释放。栈内存分配运算内置于处理器的指令集中,效率很高,不同的操作系统对栈都有一定的限制。 堆上的内存分配,亦称动态内存分配。程序在运行的期间用malloc申请的内存,这部分内存由程序员自己负责管理,其生存期由开发者决定:在何时分配,分配多少,并在何时用free来释放该内存。这是唯一可以由开发者参与管理的内存。使用的好坏直接决定系统的性能和稳定。

由上可知,但我们需要的内存很少,你又能确定你到底需要多少内存时,请用栈。而当你需要在运行时才知道你到底需要多少内存时,请用堆。

最后针对第三个问题,栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率 比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在 堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会 分 到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。

由上可知,能用栈则用栈。

#include <stdio.h>
#include <stdlib.h>
void main()
{
     int n,*p,i,j,m;
     printf("本程序可对任意个整数排序;\n");
     printf("请输入整数的总个数: ");
     scanf("%d",&n);
     p=(int *)calloc(n,sizeof(int));    //运行时决定内存分配大小
     if(p==0)   {
      printf("分配失败!\n");
      exit(1);
 }
时间: 2024-10-10 06:12:00

C++用new创建对象和不用new创建对象的区别解析的相关文章

JS中用new创建对象与不用new创建对象区别:

1 function classA() { 2 console.log(this); 3 var that = this == window ? {} : this; 4 that.name = "classA"; 5 return that; 6 } 7 8 new classA(); // 是一个classA的实例 9 classA(); // 输出了window 10 11 var obj1 = new classA(); 12 var obj2 = classA(); 13 1

FAQ: C++中定义类的对象:用new和不用new有何区别?

C++用new创建对象和不用new创建对象的区别解析 作者: 字体:[增加 减小] 类型:转载 时间:2013-07-26 我要评论 在C++用new创建对象和不用new创建对象是有区别的,不知你是否清楚的了解它们到底有什么样的区别呢?下面小编就用示例来告诉大家吧,需要的朋友可以过来参考下 我们都知道C++中有三种创建对象的方法,如下: 复制代码 代码如下: #include <iostream> using namespace std; class A { private: int n; p

C++语言动态创建对象

焦头烂额的考试月终于过去了,终于有时间能停下来思考记录一下这一个月学过的东西,首先先总结一下,在自己仿写魂斗罗游戏时遇见的问题之一,人物在移动的时候如何去判断什么时候掉入水中显示水中画面,什么时候敌人该开枪,这个时候我使用了一堆数字来描述地图,如图 但是在代码实现时,就得用一大堆判断,来判断何时应该创建对象来调用成员函数,其代码繁杂不说,更加降低了代码的复用性,如果我想在其中添加功能,还得再修改代码,这个时候我就想到了动态创建数组这个东西,根据我输入的数字长度,数组可以自动去增长,那对象是不是可

JavaScript学习总结--创建对象(2)

由于网络原因,所以写了一半就赶紧发了... 书接上回 既然工厂模式创建的对象不属于任何类型,我们知道JavaScript中实际上是没有类(class)这个概念的,所以我们需要创建一个伪类,这就用到了构造函数模式 2.构造函数模式 所谓构造函数,就是将工厂模式改写一下,使用new关键字,模仿JavaScript内置对象的形式来创建对象 我们知道JavaScript的内置对象(Array.Function等),创建时一般是 var aArr=new Array()的写法,且内置对象的首字母为大写,所

JavaScript创建对象的几种方式总结

ECMA把对象定义为:无序属性的集合,其属性可以包含基本值.对象或者函数. 1. 使用Object构造函数创建对象 创建自定义对象的最简单的方式就是创建一个Object的实例,然后再为它添加属性和方法. //通过Object构造函数的实例创建对象 var person = new Object(); //添加属性和方法 person.name = "guo"; person.age = '24'; person.sayName = function(){ console.log(thi

【天赢金创】面向对象的程序设计之创建对象

对象的定义:无序属性的集合,属性的值可以是基本值.对象或者函数. 每个对象都是基于一个应用类型创建的,这个引用类型可以是内置的(例如Object Array Math),也可以是用户自定义的. 基于Object创建对象 所有的对象都是继承自Object的,因此我们可以从Object着手创建对象. //通过new 关键字创建对象 var person = new Ojbect(); person.name = 'yuhualinfeng'; person.age = 30; person.job

SpringIOC容器-创建对象

SpringIOC容器,是spring核心内容.功能:创建对象,处理对象的依赖关系 IOC容器创建对象: 创建对象, 有几种方式: 1) 调用无参数构造器 2) 带参数构造器 3) 工厂创建对象 工厂类,静态方法创建对象 工厂类,非静态方法创建对象 spring配置文件在创建对象的配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframewo

第184天:js创建对象的几种方式总结

1.面向对象编程(OOP)的特点: 抽象:抓住核心问题 封装:只能通过对象来访问方法 继承:从已有的对象下继承出新的对象 多态:多对象的不同形态 一.创建对象的几种方式 javascript 创建对象简单的来说,无非就是使用内置对象或各种自定义对象,当然还可以使用JSON,但写法有很多,也能混合使用. 1.工厂方式创建对象:面向对象中的封装函数(内置对象) 1 function createPerson(name){ 2 //1.原料 3 var obj=new Object(); 4 //2.

再看ExpressionTree,Emit,反射创建对象性能对比

[前言] 前几日心血来潮想研究着做一个Spring框架,自然地就涉及到了Ioc容器对象创建的问题,研究怎么高性能地创建一个对象.第一联想到了Emit,兴致冲冲写了个Emit创建对象的工厂.在做性能测试的时候,发现居然比反射Activator.CreateInstance方法创建对象毫无优势可言.继而又写了个Expression Tree的对象工厂,发现和Emit不相上下,比起系统反射方法仍然无优势可言. 第一时间查看了园内大神们的研究,例如: Leven 的 探究.net对象的创建,质疑<再谈A