C++ new函数的背后

在C++中,new操作主要是分为一下三个版本:[来自cplusplus.com]

首先,如果要求你new一个int,你会觉得 so easy。直接

int *p = new int(5);

int *p = new int;

new操作实际上执行了3个步骤: 在堆上分配一块内存,调用构造函数(对于简单类型,则省略了第二步),以及返回指针。

接下类,复杂一点,为下面的类new一个对象,

class A

{

private: int a;

public: A(int _a):a(_a) {   };

};

A *pa = new A; //错误,A并没有默认构造函数(题外话了!)

A *pa = new A(3);  这一句相当于执行了下面的三行代码:

A *pa = (A*)malloc(sizeof(A));

pa->A::A(3);

return pa;

啊哦,正好印证了上面的三个步骤。

在实际的应用程序中,建议使用new操作符,因为上述malloc如果调用失败,是不会自动调用内存分配失败的函数的,但是如果使用new的话是可以的,建议参考 STL库的alloc空间配置器,讲的很详细。

其次: 对于上述的三个new函数的使用方法,此处做一个简单的测试,便可见一斑:

版本1与版本2只是重载的关系,对于 nothrow_t ,其实就是标准库为了重载这个函数引入的一个常量,该变量是个struct,定义为   struct nothrow_t{   };    结构体为空。

版本2在内存分配失败后是不会抛出异常的,而是以返回一个null指针来代替。

版本3很有意思,仅仅只是返回ptr的值,不会分配内存空间。如果使用一个new操作符的结果来调用该函数,那么就相当于在该内存上执行对应类型的构造函数.

上述代码的执行结果:

可以很清楚的看到,new (pa2) A; 该行代码并没有分配空间,因为它的内存地址与pa2是完全一致的。

pa3只是分配内存,并没有创建构造函数,也就没有调用构造函数,输出了一个空行~~

Note:

STL库中的new与delete在底层都是通过malloc和free来实现的。区别就是,malloc不会自动调用内存分配失败函数。

时间: 2024-08-28 03:55:49

C++ new函数的背后的相关文章

C++经典问答 inline 函数

inline函数的作用是什么? 在某些情况下,inline函数能使受计算量限制的应用程序运行的更快. 从广义上讲,inline函数的背后的思想是在调用函数的地方插入该函数的代码. 关键字"inline"和"inlined"函数之间的联系是什么? 用关键字inline修饰的函数可能不被直接插入,而直接插入的函数也可能不被标明为inline,被直接插入的惟一确定方式是根本不存在的! 关于直接插入有什么特殊的规则吗? 1.任何包含inline函数用法的源文件都必须包含该函

js 节流函数

函数节流背后的基本思想是,某些代码不可以在没有间断的情况连续重复执行.第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码. 当第二次调用该函数时,它会清除前一次的定时器并设置另一个.如果前一个定时器已经执行过了,这个操作就没有任何意义.然而,如果前一个定时 器尚未执行,其实就是将其替换为一个新的定时器.目的是只有在执行函数的请求停止了一段时间之后才执行.     function throttle ( method , context ){                clearTi

javascript中的this与函数讲解

前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码,都存放在Window函数内(这是个假设),也就是说javascript中只有函数作用域(前面假设做前提下). 作用域是什么 作用域是一个盒子,盒子内部的变量只能在当前盒子中使用,作用域盒子是可以嵌套的,内部盒子的变量对父级盒子是不可见的,因为盒子封闭了他们并且盒子不透明,但是盒子可以看到父级盒子内部

avascript中的this与函数讲解

徐某某 一个半路出家的野生程序员 javascript中的this与函数讲解 前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码,都存放在Window函数内(这是个假设),也就是说javascript中只有函数作用域(前面假设做前提下). 作用域是什么 作用域是一个盒子,盒子内部的变量只能在当前盒子中使用,作用域盒子是可以嵌套的,内部盒子的变量对父级

简述JavaScript函数节流

为什么要用函数节流 浏览器中某些计算和处理要比其他的昂贵很多.例如,DOM 操作比起非 DOM 交互需要更多的内存和 CPU 时间.连续尝试进行过多的 DOM 相关操作可能会导致浏览器挂起,有时候甚至会崩溃.尤其在 IE 中使用 onresize 事件处理程序的时候容易发生,当调整浏览器大小的时候,该事件会连续触发.在 onresize 事件处理程序内部如果尝试进行 DOM 操作,其高频率的更改可能会让浏览器崩溃.为了绕开这个问题,你可以使用定时器对该函数进行节流. 常见的有:重新调整浏览器窗口

函数节流之debounce

浏览器中某些计算和处理要比其他的昂贵很多.例如, DOM 操作比起非 DOM 交互需要更多的内存和 CPU 时间.连续尝试进行过多的 DOM 相关操作可能会导致浏览器挂起,有时候甚至会崩溃.尤其在 IE 中使用 onresize 事件处理程序的时候容易发生,当调整浏览器大小的时候,该事件会连续触发.在 onresize 事件处理程序内部如果尝试进行 DOM 操作,其高频率的更改可能会让浏览器崩溃.为了绕开这个问题,你可以使用定时器对该函数进行节流. 函数节流背后的基本思想是指,某些代码不可以在没

Sigmoid函数总结

Sigmoid函数又叫Logistic函数,它在机器学习领域有极其重要的地位. 目录一 函数基本性质二 Sigmoid函数与逻辑回归三 为什么要选择Sigmoid函数LR的需求选择Sigmoid是可以的Sigmoid特殊的性质为什么选择Sigmoid正态分布解释最大熵解释四 总结 一. 函数基本性质首先Sigmoid的公式形式: 函数图像: 函数的基本性质: 1.定义域:(−∞,+∞)(−∞,+∞)2.值域:(−1,1)(−1,1)3.函数在定义域内为连续和光滑函数4.处处可导,导数为:f′(x

272 函数的理解和使用:回调函数,匿名函数自调用IIFE,**函数中的this**

什么是函数? 用来实现特定功能的, n条语句的封装体 只有函数类型的数据是可以执行的, 其它的都不可以 为什么要用函数? 提高复用性 便于阅读交流 函数也是对象 instanceof Object===true 函数有属性: prototype 函数有方法: call()/apply() 可以添加新的属性/方法 函数的3种不同角色 一般函数 : 直接调用 构造函数 : 通过new调用 对象 : 通过.调用内部的属性/方法 函数中的this 显式指定谁: obj.xxx() 通过call/appl

从mixin到new和prototype:Javascript原型机制详解

这是一篇markdown格式的文章,更好的阅读体验请访问我的github,移动端请访问我的博客 继承是为了实现方法的复用,如何实现方法的复用呢?最容易想到的,就是: ```js//mixinfunction extend(optional, base){ for(var prop in base){ if(!prop in optional){ optional[prop] = base[prop] } } return optional}``` 这种方法俗称`mixin`,它直接从甲对象复制方