当写出这样的代码的时候, 实际上有两步操作:

p = new P();

  1.分配内存,
  2.然后在分配好的内存之上初始化类成员.

第二步是有构造函数完成的, 第一步就是new函数的工作.

全局的new有六种重载形式,

void *operator new(std::size_t count)
throw(std::bad_alloc); //一般的版本 void *operator new(std::size_t count, //兼容早版本的new
const std::nothrow_t&) throw(); //内存分配失败不会抛出异常 void *operator new(std::size_t count, void *ptr) throw();
//placement版本
void *operator new[](std::size_t count) //
throw(std::bad_alloc); void *operator new[](std::size_t count, //
const std::nothrow_t&) throw(); void *operator new[](std::size_t count, void *ptr) throw();

  所以, 刚才的用法, 就是使用new函数的一种重载形式.
  如果A这个对象以同样实行重载了new函数的化, 作为成员函数会被优先调用.

C++的各种new简介

1.new T

  第一种new最简单,调用类的(如果重载了的话)或者全局的operator new分配空间,然后用类型后面列的参数来调用构造函数,用法是

new TypeName(initial_args_list)

  如果没有参数,括号一般可以省略。例如:

int *p=new int;
int *p=new int(10);
int *p=new foo("hello");

  通过调用delete来销毁:

delete p;

2. new T[]
  这种new用来创建一个动态的对象数组,他会调用对象的operator new[]来分配内存(如果没有则调用operator new,搜索顺序同上),然后调用对象的默认构造函数初始化每个对象。
  
  用法:

new TypeName[num_of_objects];

  例如:

int *p= new int[10];

  销毁时使用

operator delete[]

3.new()T 和new() T[]
  这是个带参数的new,这种形式的new会调用operator new(size_t,OtherType)来分配内存这里的OtherType要和new括号里的参数的类型兼容。
  这种语法通常用来在某个特定的地址构件对象,称为placement new,前提是operator new(size_t,void*)已经定义,通常编译器已经提供了一个实现,包含<new>头文件即可,这个实现只是简单的把参数的指定的地址返回,因而new()运算符就会在括号里的地址上创建对象。

  需要说明的是,第二个参数不是一定要是void*,可以识别的合法类型,这时候由C++的重载机制来决定调用那个operator new。

  当然,我们可以提供自己的operator new(size_,Type),来决定new的行为,比如

char data[1000][sizeof(foo)];
inline void* operator new(size_t ,int n)
{
return data[n];
}

  就可以使用这样有趣的语法来创建对象:

foo *p=new(6) foo(); //把对象创建在data的第六个单元上

  标准库还提供了一个nothrow的实现:

void* operator new(std::size_t, const std::nothrow_t&) throw();
void* operator new[](std::size_t, const std::nothrow_t&) throw();

  就可以实现调用new失败时不抛出异常

new(nothrow) int(10);
// nothrow 是std::nothrow_t的一个实例

  placement new 创建的对象不能直接delete来销毁,而是要调用对象的析够函数来销毁对象,至于对象所占的内存如何处理,要看这块内存的具体来源。

4. operator new(size_t)
  这个的运算符分配参数指定大小的内存并返回首地址,可以为自定义的类重载这个运算符,方法就是在类里面声明加上

void *operator new(size_t size)
{
//在这里分配内存并返回其地址
}

  无论是否声明,类里面重载的各种operator new和operator delete都是具有static属性的一般不需要直接调用operator new,除非直接分配原始内存(这一点类似于C的malloc),在冲突的情况下要调用全局的operator加上::作用域运算符:

::operator new(1000); // 分配1000个字节

  返回的内存需要回收的话,调用对应的operator delete

5.operator new[](size_t)

  这个也是分配内存,,只不过是专门针对数组,也就是new T[]这种形式,当然,需要时可以显式调用

6.operator new(size_t size, OtherType other_value)
  和operator new[](size_t size, OtherType other_value)
  参见上面的new()
  需要强调的是,new用来创建对象并分配内存,它的行为是不可改变的,可以改变的是各种operator new,我们就可以通过重载operator new来实现我们的内存分配方案.

C++-new 的六种重载形式的更多相关文章

  1. 《从零开始学Swift》学习笔记(Day 7)——Swift 2.0中的print函数几种重载形式

    原创文章,欢迎转载.转载请注明:关东升的博客 Swift 2.0中的print函数有4种重载形式: l   print(_:).输出变量或常量到控制台,并且换行. l   print(_:_:).输出 ...

  2. File类的构造方法:三种重载形式(新手)

    //导入的包.import java.io.File;//File类的构造方法 三种重载形式//创建的一个类.public class zylx1 { //公共静态的主方法. public stati ...

  3. C++运算符重载形式——成员函数or友元函数

    运算符重载是C++多态的重要实现手段之一.通过运算符重载对运算符功能进行特殊定制,使其支持特定类型对象的运算,执行特定的功能,增强C++的扩展功能. 运算符重载的我们需要坚持四项基本原则: (1)不可 ...

  4. C#-MessageBox全部函数重载形式及举例

    Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.D ...

  5. C++ new 解析重载

    C++ new 解析重载 new的三种形式: (1)operator new(运算符new) (2)new operator(new 操作) (3)placement new(特殊的new操作)(不分 ...

  6. 深入new/delete:Operator new的全局重载

    Operator new 的全局重载 原文地址:http://blog.csdn.net/zhenjing/article/details/4354880 我们经常看到这么一句话: operator ...

  7. operator new与new operator的区别

    原文地址:http://www.cnblogs.com/jamesmile/archive/2010/04/17/1714311.html,在此感谢 C++中的operator new与new ope ...

  8. operator new,new operator,placement new的区别

    原文地址:http://www.cnblogs.com/jamesmile/archive/2010/04/17/1714311.html,在此感谢 C++中的operator new与new ope ...

  9. C++重载new和delete运算符

    内存管理运算符 new.new[].delete 和 delete[] 也可以进行重载,其重载形式既可以是类的成员函数,也可以是全局函数.一般情况下,内建的内存管理运算符就够用了,只有在需要自己管理内 ...

随机推荐

  1. 【redis】spring boot利用redis的Keyspace Notifications实现消息通知

    前言 需求:当redis中的某个key失效的时候,把失效时的value写入数据库. github: https://github.com/vergilyn/RedisSamples 1.修改redis ...

  2. Case Study - 用户复购行为预测

    Problem 对于商家来说提前识别回头客是一件集中资源提高新品销售量的头等大事,各大商家为了吸引顾客的二次购买都会实行各种像是促销.优惠券.折扣之类的策略.按理说越了解客户,越知道客户的喜好,越能精 ...

  3. Callablestatement与JavaBean及其实例

    一. Callablestatement:调用 数据库中的存储过程.存储函数 connection.prepareCall(参数:存储过程/存储函数名)参数格式:存储过程:(无返回值return,用O ...

  4. C#排序算法的实现---选择排序

    一.算法原理 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完. 选择排序算法的运作如下: 1.对比数组中前一个元素跟后一个元素的大小 ...

  5. 【jQuery实例】Ajax登录页面

    登录界面是信息系统提供的必备的功能,是提供给用户提供维护信息的接口.接下来,我来带领大家打造一个漂亮.安全的登录界面,使用的技术是ASP.NET+jQuery 先来看看预览效果   Ajax登录重点在 ...

  6. Yarn报错:Exception message: /bin/bash: line 0: fg: no job control

    Exception message: /bin/bash: line 0: fg: no job control 这个错误是 本地idea跨平台远程调试hadoop集群出现的,在使用windows调用 ...

  7. babel配置文件.babelrc

    Babel是一个广泛应用的转码器,可以将ES6代码转为ES5代码,从而在现有环境执行.意味着可以使用ES6编写程序,而不用担心现有环境是否支持. Babel的配置文件是.babelrc,存放在项目的根 ...

  8. Linux C++ 单链表添加,删除,输出,逆序操作

    /*单链表操作*/#include <iostream>using namespace std; class Node{ public: Node(){ next=0; } Node(in ...

  9. adworld MISC002 | Linux的挂载文件系统的运用

    EXT3是第三代扩展文件系统(英语:Third extended filesystem,缩写为ext3),是一个日志文件系统,常用于Linux操作系统. Plan 1: 直接将附件使用mount命令挂 ...

  10. 栈和队列----最大值减去最小值小于等于num的子数组的数量

    最大值减去最小值小于等于num的子数组的数量 给定数组arr和整数 num,共返回有多少个数组满足下列情况: max(arr[i..j])-min(arr[i..j])<=num.其中max(a ...