c/c++ 重载new,delete运算符 placement new
重载new,delete运算符
new,delete在c++中也被归为运算符,所以可以重载它们。
new的行为:
先开辟内存空间
再调用类的构造函数
开辟内存空间的部分,可以被重载。
delete的行为:
先调用类的析构函数
再释放内存空间
释放内存空间的部分,可以被重载。
为什么要要重载它们?
有时需要实现内存池的时候需要重载它们。频繁的new和delete对象,会造成内存碎片,内存不足等问题,影响程序的正常执行,所以一次开辟一个适当大的空间,每次需要对象的时候,不再需要去开辟内存空间,只需要调用构造函数(使用placement new)即可。
new,delete的重载函数,可以是全局函数,也可以是类内部的公有重载函数;当既有全局的重载函数,也有类内部的公有重载函数时,实际调用的是类内部的公有重载函数。
new,delete可以有多种重载方式,但是,new函数的第一个参数一定要是size_t类型
重载方式1,new单个对象
void* operator new(size_t sz){
void* o = malloc(sz);
return o;
}
void operator delete(void *o){
free(o);
}
重载方式2,new对象的数组
void* operator new[](size_t sz){
void* o = malloc(sz);
return o;
}
void operator delete[](void *o){
free(o);
}
重载方式3,不开辟空间,只是调用给定对象(用地址识别)的构造方法,也叫placement new
//第一个参数size_t即使不使用,也必须有
void* operator new(size_t sz, String* s, int pos){
return s + pos;
}
小例子:
#include <iostream>
#include <string.h>
using namespace std;
class String{
public:
String(const char* str = ""){
cout << "Create" << endl;
if(NULL == str){
data = new char[1];
data[0] = '\0';
}
else{
data = new char[strlen(str) + 1];
strcpy(data, str);
}
}
~String(){
cout << "Free" << endl;
delete []data;
data = NULL;
}
private:
char* data = NULL;
};
//重载方式1
void* operator new(size_t sz){
cout << "in operator new" << endl;
void* o = malloc(sz);
return o;
}
void operator delete(void *o){
cout << "in operator delete" << endl;
free(o);
}
//重载方式2
void* operator new[](size_t sz){
cout << "in operator new[]" << endl;
void* o = malloc(sz);
return o;
}
void operator delete[](void *o){
cout << "in operator delete[]" << endl;
free(o);
}
//重载方式3
//第一个参数size_t即使不适用,也必须有
void* operator new(size_t sz, String* s, int pos){
return s + pos;
}
int main(){
String *s = new String("abc");
delete s;
String *sr = new String[3];
delete []sr;
//开辟内存池,但是还没有调用过池里对象的构造方法
String *ar = (String*)operator new(sizeof(String) * 2);
//调用池里第一个对象的构造方法,不再开辟空间
new(ar, 0)String("first0");
//调用池里第二个对象的构造方法 ,不再开辟空间
new(ar, 1)String("first1");
//调用池里第一个对象的析构方法,注意不会释放到内存
(&ar[0])->~String();
//调用池里第二个对象的析构方法,注意不会释放到内存
(&ar[1])->~String();
//下面语句执行前,内存池里的对象可以反复利用
operator delete(ar);
}
c/c++ 重载new,delete运算符 placement new的更多相关文章
- C++重载new和delete运算符
内存管理运算符 new.new[].delete 和 delete[] 也可以进行重载,其重载形式既可以是类的成员函数,也可以是全局函数.一般情况下,内建的内存管理运算符就够用了,只有在需要自己管理内 ...
- C++学习32 重载new和delete运算符
内存管理运算符 new.new[].delete 和 delete[] 也可以进行重载,其重载形式既可以是类的成员函数,也可以是全局函数.一般情况下,内建的内存管理运算符就够用了,只有在需要自己管理内 ...
- 重载new和delete运算符
内存管理运算符 new.new[].delete 和 delete[] 也可以进行重载,其重载形式既可以是类的成员函数,也可以是全局函数.一般情况下,内建的内存管理运算符就够用了,只有在需要自己管理内 ...
- C++ new operator, delete operator, operator new, operator delete, new placement
http://www.younfor.com/cpp-new-placement-new-operator-new.html http://www.cnblogs.com/luxiaoxun/arch ...
- C++重载流插入运算符和流提取运算符【转】
C++的流插入运算符“<<”和流提取运算符“>>”是C++在类库中提供的,所有C++编译系统都在类库中提供输入流类istream和输出流类ostream.cin和cout分别是 ...
- C++运算符重载——输入/输出运算符
为了与IO标准库一致,重载输入输出运算符函数的第一个行参应该是流的引用,第二个行参是对象的引用. 如果重载为类的成员函数,第一个行参应该是对象的引用,第二个行参是流的引用. 使用方式是 ClassOb ...
- operator 重载内置运算符
operator 关键字来重载内置运算符,或提供类或结构声明中的用户定义转换.它可以定义不同类型之间采用何种转化方式和转化的结果. operator用于定义类型转化时可采用2种方式,隐式转换(impl ...
- C++中不可重载5个运算符
C++中不可重载的5个运算符 C++中的大部分运算符都是可以重载的,只有以下5个运算符不可以重载,他们是: 1 .(点运算符)通常用于去对象的成员,但是->(箭头运算符),是可以重载的 2 ...
- 用new和delete运算符进行动态分配和撤销存储空间
測试描写叙述:暂时开辟一个存储空间以存放一个结构体数据 #include <iostream> #include <string> using namespace std; s ...
随机推荐
- Hadoop YARN架构设计要点
YARN是开源项目Hadoop的一个资源管理系统,最初设计是为了解决Hadoop中MapReduce计算框架中的资源管理问题,但是现在它已经是一个更加通用的资源管理系统,可以把MapReduce计算框 ...
- 【mac】ansible安装及基础使用
安装 环境释放 mac 10.12.5 #more /System/Library/CoreServices/SystemVersion.plist 安装命令 #ruby -e "$(cur ...
- 为Linux配置常用源:epel和IUS
CentOS上,除了os类的yum源,还需要配置几个常用的源:epel.ius. 有很多国内很多镜像站点都提供了各类仓库的镜像站点,个人感觉比较全的是阿里云http://mirrors.aliyun. ...
- IPv6笔记
单播地址包含的几种类型:1.AGUA地址:2000::到3FFF:FFFF:FFFF:FFFF:FFFF..... 一个接口可以拥有若干个AGUA地址2.Link-Local 地址:FE80::/10 ...
- shell编程基础(七): 处理文件命令sed与awk
一.sed(以行为单位处理文件) sed意为流编辑器(Stream Editor),在Shell脚本和Makefile中作为过滤器使用非常普遍,也就是把前一个程序的输出引入sed的输入,经过一系列编辑 ...
- .net DBHelper
DBHelper.cs是程序来连接数据的,也是一个程序必不可少的一个类(本人道行浅,目前这样认为).由于一个程序基本写一次,容易忘记.所有写在这里备注 首先是引用 using System.Data; ...
- [转]OmniLayer / omnicore API 中文版
本文转自:https://www.codetd.com/article/1692438 JSON-RPC API Omni Core是Bitcoin Core的一个分支,其Omni协议功能支持作为顶层 ...
- 【转】JS正则表达式大全(整理详细且实用)
正则表达式中的特殊字符 字符 含意 \ 做为转意,即通常在"\"后面的字符不按原来意义解释,如/b/匹配字符"b",当b前面加了反斜杆后/\b/,转意为匹配一个 ...
- 一个小时学会Maven
一.为什么要Maven 在开发中经常需要依赖第三方的包,包与包之间存在依赖关系,版本间还有兼容性问题,有时还里要将旧的包升级或降级,当项目复杂到一定程度时包管理变得非常重要. Maven是当前最受欢迎 ...
- 关于Maven项目build时出现No compiler is provided in this environment的处理
版权声明:本文为博主原创文章,未经博主允许不得转载. http://blog.csdn.net/lslk9898/article/details/73836745 近日有同事遇到在编译Maven项目时 ...