• 18.5 重载全局new、delete、定位new及重载等


    一:重载全局operator new和operator delete操作符

    #include 
    
    using namespace std;
    
    void* operator new(size_t size)
    {
    	return malloc(size);
    }
    
    void* operator new[](size_t size)  //数组版本
    {
    	return malloc(size);
    }
    
    void operator delete(void* phead)
    {
    	free(phead);
    }
    
    void operator delete[](void* phead)
    {
    	free(phead);
    }
    
    class A
    {
    public:
    	int m_i;
    	int m_j;
    	A()
    	{
    		cout << "A::A()" << endl;
    	}
    	~A()
    	{
    		cout << "A::~A()" << endl;
    	}
    
    public:
    	void* operator new(const size_t size)
    	{
    		A* ppoint = (A*)malloc(size);
    		return ppoint;
    	};
    
    	void* operator new[](const size_t size)  //数组版本
    	{
    		A* ppoint = (A*)malloc(size);
    		return ppoint;
    	};
    
    	void operator delete(void* phead)
    	{
    		free(phead);
    	};
    
    	void operator delete[](void* phead)
    	{
    		free(phead);
    	};
    };
    
    void func()
    {
    	int* pint = new int(10);
    	delete pint;
    
    	char* parr = new char[20];
    	delete[] parr;
    
    	A* pa1 = new A();
    	delete pa1;
    
    	A* pa2 = new A[5]();
    	delete[] pa2;
    }
    
    int main()
    {
    	func();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    二:定位new(placement new)

    有placement new,但是没有对应的placement delete

    功能:在已经分配的原始内存中初始化一个对象;
    1、已经分配,定位new并不分配内存,你需要提前将这个定位new要使用的内存分配出来;
    2、初始化一个对象(初始化一个对象的内存),我们可以理解成调用这个对象的构造函数;所以,定位new就是能够在一个预先分配好的内存地址上构造一个对象。

    格式:
    new (地址) 类类型(参数)

    #include 
    
    using namespace std;
    
    class A
    {
    public:
    	int m_a;
    
    public:
    	A() :m_a(10)
    	{
    		int test;
    		test = 1;
    	}
    	A(int tmpvalue) : m_a(tmpvalue)
    	{
    		int test;
    		test = 1;
    	}
    	~A()
    	{
    		int test;
    		test = 1;
    		cout << "A::~A()" << endl;
    	}
    
    	//operator new重载
    	void* operator new(const size_t size)
    	{
    		cout << "void* operator new(const size_t size)" << endl;
    		A* ppoint = (A*)malloc(size);
    		return ppoint;
    	}
    
    	//定位new操作符的重载
    	void* operator new(size_t size, void* phead)
    	{
    		cout << "void* operator new(size_t size, void *phead)" << endl;
    		return phead;  //收到内存开始地址,只需要原路返回
    	}
    };
    
    void func()
    {
    	void* mymemPoint1 = (void*)new char[sizeof(A)];  //内存必须事先分配出来
    	A* pmyAobj1 = new(mymemPoint1)A();  //调用无参构造函数,这里并不会额外分配内存
    
    	void* mymemPoint2 = (void*)new char[sizeof(A)];
    	A* pmyAobj2 = new(mymemPoint2)A(10);  //调用带一个参数的构造函数,这里并不会额外分配内存
    
    	//delete pmyAobj1;
    	//delete pmyAobj2;
    
    	pmyAobj1->~A();  //手工调用析构函数是可以的,但是手工调用构造函数一般不可以
    	pmyAobj2->~A();
    
    	delete[](void*) pmyAobj1;
    	delete[](void*) pmyAobj2;
    }
    
    int main()
    {
    	func();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    三:多种版本的operator new重载

    可以重载很多版本的operator new,只要每个版本参数不同就行,但是第一个参数是固定的,必须为size_t,表示要new对象的sizeof值。

    如果自定义了operator new重载,系统将不会生成默认重载。并且,自定义重载不会调用构造函数。

    #include 
    
    using namespace std;
    
    class A
    {
    public:
    	int m_a;
    
    public:
    	A()
    	{
    		cout << "A::A()" << endl;
    	}
    	~A()
    	{
    		cout << "A::~A()" << endl;
    	}
    
    	void* operator new(const size_t size)
    	{
    		cout << "void* operator new(const size_t size)" << endl;
    		return nullptr;
    	}
    
    	void* operator new(const size_t size, int tvp1, int tvp2)
    	{
    		cout << "void* operator new(const size_t size, int tvp1, int tvp2)" << endl;
    		return nullptr;
    	}
    };
    
    void func()
    {
    	A* pa1 = new A();
    	A* pa2 = new (10, 20) A();
    }
    
    int main()
    {
    	func();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
  • 相关阅读:
    第五章第二节:树和森林
    SpringCloud——什么是微服务
    Cobalt Strike (CS) 逆向初探
    LyScript 实现对内存堆栈扫描
    【Cookie,Session,Token,JWT的区别】
    Java日期时间类
    C/C++指针
    Elasticsearch ES数据迁移方法及注意事项
    Kafka 面试连环炮, 看你能撑到哪一步?
    Nanoframework 操作单片机蓝牙配置WIFI的案例
  • 原文地址:https://blog.csdn.net/zzyzxb/article/details/128052457