当前位置 : 主页 > 编程语言 > c++ >

c++中new的知识点

来源:互联网 收集:自由互联 发布时间:2021-06-23
在练习内存池时,发现需要重载new,可是这个重载只是重载了operator new,那么还有哪几种new呢,下面来记录一下 首先记录一个点,在类中重载operator new, 默认就是静态成员函数, 所以

在练习内存池时,发现需要重载new,可是这个重载只是重载了operator new,那么还有哪几种new呢,下面来记录一下

首先记录一个点,在类中重载operator new,默认就是静态成员函数,所以不能生命为虚函数,不能调用非静态成员变量

 

下面正文,c++有三种new

说的通俗点。1、new运算符(new operator)大哥,我们在代码中直接使用的就是它。它做2件事:调用后两种new申请内存和初始化对象。2、operator new,是一个函数,所以也是三种new唯一一个可以重载的。它类似C语言中的malloc,用于分配内存。3、placement new,用于初始化对象(如果有的话,就是它调用构造函数)

1.operator new

operator new和operator delete有两个重载版本,每个版本支持相关的new表达式和delete表达式:

void *operator new(size_t);

void *operator new[](size_t);

void *operator delete(void*);

void *operator delete[](void*);

入参类型必须为size_t,返回类型必须为void *.可以重载为多个参数版本如下

void *operator new(size_t t1,size_t t2);
这样如果调用未 void *p= new(10) int;时 t2的大小就为10.而t1的大小一直是固定的(可能根据系统不同而变化)
这个是我们唯一可以重载的new,不仅可以在类内重载,全局operator new也可以被重载。如果全局operator new被重载的话,那么除了类内的重载会覆盖全局的重载,任何地方调用new 都会调用到这个全局重载的函数里

2.new operator
当你写string *ps = new string(“Hands up!”)时,你所使用的new是所谓的new operator,它其实干了两件事:
一、分配足够的内存(实际大小是大于所创建的对象大小,因为有管理的数据),即operator new。
二、调用对象构造函数,new operator永远干这两件事。上面的那段代码大约反映以下的行为
void *mem = operator new(sizeof(string));
call string::string(“Hands up!”) on *mem;//只能由编译器完成,用户是不允许这样操作的,也就是说如果你想建立一个堆对象就必须用new操作符,不能直接像上面一样调用构造函数来初始化堆对象。

也就是说operator new仅仅分配内存(就像malloc一样),我们能够做的仅仅是重载operator new,为自己的类创建一个定制的内存管理方案,
这也让我有点明白为什么在重载operator new的时候并没有写调用构造函数的代码,但它确实被调用了,原来都是new operator搞的鬼。

 

 

 编译器看到类类型的new或者delete表达式的时候,首先查看该类是否是有operator new或者operator delete成员,如果类定义了自己的new和delete函数,则使用这些函数为对象分配和释放内存,否则调用标准库版本。如果你想定制自己独有的内存分配过程,你应该重载全局的operator new函数,然后使用new操作符,new操作符会调用你定制的operator new。当然你可以显示的调用:: operator new和:: operator delete强制使用全局的库函数

 

3.定位new表达式

即placement new,定位new表达式在已分配的与原始内存中初始化一个对象,他与new的其他版本不同,它不分配内存。相反,它接受指向已分配好但未构造的内存指针,并在该内存中初始化一个对象。实际上,定位new表达式使我们在特定的、预分配的内存地址构造一个对象。它可以定义类的任何构造函数。

         new(place_address) type

         new(place_address) type(initializer_list)

举个例子,

我们也可以直接来使用它,你手上有一块内存p。int *p2 = new (p) int(100); 这样你就用placement new把一块内存初始化为int,并给它个初值100。其实这里,p所指向的内存可以是堆也可以是栈。如果是栈内存被这样new,不需要delete,且可以反复的new。这有什么用, 你可以把动态分配内存的请求限制在一块区域内,这就有点像操作系统给引用程序分配内存,这一块给你随便用, 妨碍不到其他的内存。算是一种安全策略吧。

网友评论