写在前面:感谢GeekBand提供这样好的学习机会,让我在繁忙的工作之余可以学习巩固c++知识。以下是边学边记的一些扩展点。分享给大家。
关于重写new 和 delete,一共有两种:全局(Global)的一种,建立在类中(InClass)的一种如果一个类里面没有InClass的new 、delete函数,可以用Global的。
先说重写全局的,先看调用方法,再看重写实现过程。```
//调用方法
::new(20) Apple;
::delete apple1;
//实现过程
void* operator new(std::size_t size, long extra)
{
// available memory space check
void *storage = malloc(size + extra);
if (NULL == storage)
{
throw "allocation fail : no free memory";
}
// using available memory as checked
std::printf("GLOBAL:: operator new(std::size_t size) size = %zu extra = %zu\n", size, extra);
return std::malloc(size + extra);
}
void operator delete(void* ptr) noexcept
{
std::cout << "GLOBAL:: operator delete(void*, long)" << std::endl;
std::free(ptr);
}
int main()
{
std::cout << "Start To Run Overloaded New Globaly" << std::endl;
Apple* apple1 = ::new(20) Apple;
::delete apple1;
std::cout << "Deleted with the Overloaded Delete Globaly\n" << std::endl;
return 0;
}
再来一个写在类里面的, 先来头文件
include <iostream>
class Apple {
int size;
char type;
public:
Apple() :size(0), type(0)
{
std::cout << "Apple Constructor Executed" << std::endl;
}
~Apple()
{
std::cout << "Apple Destructor Executed" << std::endl;
}
static void* operator new (std::size_t size)
{
// available memory space check
void storage = malloc(size);
if (NULL == storage)
{
throw "allocation fail : no free memory";
}
// using available memory as checked
std::printf("InClass:: Apple Operator New Executed size = %zu\n", size);
return std::malloc(size);
}
static void operator delete (void ptr) noexcept
{
std::cout << "InClass:: operator delete (void* ptr) " << std::endl;
std::free(ptr);
}
再来实现文件
include "FruitApple.h"
int main()
{
std::cout << "\nStart To Run Overloaded New in Class" << std::endl;
Apple* apple = new Apple;//[10];
delete apple;
std::cout << "Deleted with the Overloaded Delete in Class\n" << std::endl;
return 0;
}
####需要注意的地方
#####重载new()
我们可以重载new,前提是每个版本声明都必须有独特的参数列,其中第一个参数必须是std::size_t。其余参数以new所指定的placement argument为初值。下面的小括号里的“200”,就是placement argument。
Apple* a = new(200)Apple;
#####重载delete()
我们可以重载多个版本的delete,但是他们绝不会被delete调用。只有当new所调用的构造函数抛出异常,才会用这些重载版的。他们只可能这样被调用,以来归还“完全创建成功”的object所占用的内存。
#####成对调用,适用于全局的和类中的
Apple *a = ::new Apple(8); //新申请内存,并且构造
::delete a;
Apple* aArray = ::new Apple[6];
::delete [] aArray; //这里注意成对使用,不要只调用一次。
最后,推荐了一些我认为有用的参考。要知道,有很多种方式来重载new 和 delete,而且要注意用一种new重载,需要用另一种delete重载来解开。管理好内存。