重载new delete操作符是怎么调用的
自定义的new操作符是怎么对英语new 一个对象的?自定义的delete操作符什么情况下得到调用?new一个对象时出现异常需要我操心内存泄露吗?下面的一个例子帮我们解开所有的疑惑。
1. 调用规则 new(A,B) class(param) -> operator new(sizeof(class), A, B)
2. 自定义的操作符只用new对象异常的时候才会得到调用机会,而且调用哪个delete和你用的那个new一一对应,
规则是 new(X, Y) class(param); -> delete(X, Y) class;-> operator delete(X, Y, void* p)
3. 我们不用担心new对象时候引发的异常的内存泄露,c++系统会我们在异常发生的第一时间(哪怕我们定义了异常处理函数)帮助我们释放内存。
/*
运行结果:
Normal operator new called.
Normal operator delete called. Custom operator new called.
Normal operator new called.
Normal operator delete called. Normal operator new called.
Normal operator delete called.
exception Custom operator new called.
Normal operator new called.
Custom operator delete called.
Normal operator delete called.
exception 请按任意键继续. . .
*/ #include <cstddef>
#include <new>
#include <iostream>
using namespace std; void * operator new(std::size_t sz)
throw(std::bad_alloc)
{
std::cout << "Normal operator new called." << std::endl ; void * p = std::malloc(sz) ;
if (!p)
throw std::bad_alloc() ;
return p ;
} void operator delete(void * p) throw()
{
std::cout << "Normal operator delete called." << std::endl ;
if (p)
std::free(p) ;
} void * operator new(std::size_t sz, std::ostream & out)
throw(std::bad_alloc)
{
out << "Custom operator new called." << std::endl ;
return ::operator new(sz) ;
} void operator delete(void * p, std::ostream & out) throw()
{
out << "Custom operator delete called." << std::endl ;
::operator delete(p) ;
} class T
{
public:
T(bool should_throw) { if (should_throw) throw 1 ; }
} ; int main()
{
// Calls normal new, normal delete.调用标准的new、delete
T * p = new T(false) ;
delete p ;
std::cout << std::endl ; // Calls custom new, normal delete. 调用自定义的new, 标准的delete
//调用规则 new(A,B) class(param) -> operator new(sizeof(class), A, B)
p = new(std::cout) T(false) ;
delete p ;
std::cout << std::endl ; // Calls normal new, normal delete. 调用标准的new、delete 而且抛出异常
try
{
T * p = new T(true) ;
cout << "accident happens, should not get here" << endl;
//上面语句,没打印,说明不是代码调用了delete,而是c++框架自动为我们掉delete,即new失败时系统会自动为我们调用delete函数
delete p ;
}
catch (...)
{
cout << "exception" << endl;
}
std::cout << std::endl ; // Calls custom new, custom delete. 调用自定义的new、delete,这个使用我们自定义的delete会得到调用
// 规则是 new(X, Y) class(param); -> delete(X, Y) class;
try
{
T * p = new(std::cout) T(true) ;
cout << "accident happens, should not get here" << endl;
delete p ;
}
catch (...)
{
cout << "exception" << endl;
}
std::cout << std::endl ;
}
重载new delete操作符是怎么调用的的更多相关文章
- C++ 重载new和delete操作符
原因: C++标准库提供的new和delete操作符,是一个通用实现,未针对具体对象做具体分析 存在分配器速度慢.小型对象空间浪费严重等问题,不适用于对效率和内存有限制的应用场景 好处: 灵活的内 ...
- C++ Primer 学习笔记_62_重载操作符与转换 --调用操作符和函数对象
重载操作符与转换 --调用操作符和函数对象 引言: 能够为类类型的对象重载函数调用操作符:一般为表示操作的类重载调用操作符! struct absInt { int operator() (int v ...
- C++学习笔记13:运算符重载(赋值操作符2)
移动语义 完成所有权的移交,当拷贝构造和赋值构造时,目标对象的所有权必须移交给我们的新的对象,原始对象将丧失所有权,_p指针将不再指向原来的那个数组: 左值与右值 C原始定义 左值:可以出现在赋值号的 ...
- javascript之delete操作符
理解delete 理论 代码段的类型 执行上下文 活动对象 / 变量对象 属性的特性 内置属性与 DontDelete 未声明的赋值 Firebug的困惑 在eval中删除变量 浏览器兼容性 Geck ...
- C#中如何利用操作符重载和转换操作符
操作符重载 有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成 ...
- C#中如何利用操作符重载和转换操作符 (转载)
操作符重载 有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成 ...
- C++ new delete操作符
//new delete操作符 #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; /* 1.n ...
- js中的内部属性与delete操作符
本文正式地址:http://www.xiabingbao.com/javascript/2015/08/03/javascript-delete-configurable 在讲解Configurabl ...
- C++语言基础(2)-new和delete操作符
在C语言中,动态分配内存用 malloc() 函数,释放内存用 free() 函数.如下所示: ); //分配10个int型的内存空间 free(p); //释放内存 在C++中,这两个函数仍然可以使 ...
随机推荐
- CentOS 64位上编译 Hadoop 2.6.0
Hadoop不提供64位编译好的版本号,仅仅能用源代码自行编译64位版本号. 学习一项技术从安装開始.学习hadoop要从编译開始. 1.操作系统编译环境 yum install cmake lzo- ...
- iOS7支持九宫格
Beta4支持九宫格 还没试,等最终版把,现在的有很多bug还比较费电 看网上有人说虽然终于出来了但是还是不如百度搜狗等输入法方便 前几个月在weiphone上还有人问支不支持结果回帖的都说没戏 这算 ...
- java类和对象的基础(笔记)
在Java类的设计中,有时希望一个类在任何时候只能有一个实例.这时可以将该类设计为单例模式(singleton).要将一个类设计为单例模式,需要把类的构造方法的访问修饰符声明为private,然后在类 ...
- IP数据包结构
Linux 网络编程——IP 数据报格式详解 http://www.linuxidc.com/Linux/2015-04/116149.htm
- c++,虚函数
1.在声明函数时,在最前加上virtual,则该函数就是函虚数,基类的虚函数被派生类继承后仍是虚函数.2.派生类中可以重写基类的虚函数.3.用指针访问重写的虚函数时,被访问的虚函数是指针指向的对象所属 ...
- 使用Qt设计师文件的3种方式
使用Qt设计师设计的.ui界面文件是XML文件,有3种方式在PyQt中使用,本文将通过实例进行讲解. 使用PyQt中如何结合Qt设计师进行开发中的例子.点击按钮修改标签的内容. 1. 直接使用ui文件 ...
- sizeof与strlen的区别 浅谈
1.sizeof operator sizeof是C语言的一种单目操作符,如C语言的其他操作符++.- - 等,它并不是函数. Queries size of the object or type. ...
- C++ 中mallon动态分配内存大小用法
#include<iostream> using namespace std; int main(){ char *s; int n; cin>>n; s= (char *) ...
- android之wifi开发
WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为“热点 ...
- css sprites 图片精灵自动生成 插件
grunt-spritesmith https://www.npmjs.com/package/grunt-spritesmith