c++ - placement operator new() and the operator delete()

A class member operator new() can be overloaded. Provided that each delcaration has a unique paramter list. The first parameter of any class operator new() must always be a parameter of type size_t, for example. 

 

 

 

class Screen
{
public :
   void *operator new (size_t); 
   void *operator new(size_t, Screen*);
};

 

 

and how you can use the the placement operator as follow.

 

 

 

void func(Screen * start) 
{
   Screen *p = new (Start) Screen;
   //...
}

 

 

 

NOTE: it is also possible to overload the class member  operaotr delete(). However, such an operator is never inovked from a delete expression. An overloaded operator delete() is only called implicitly by the implementation if the constructor called by a new expression (yes, this is not a typo) throw an expression.

 

given the expression, 

 

 

Screen *ps = new (Start) Screen;

 

 

are as follow.

 

 

 

  1. It calls the class operaor new (size_t, Screen *)
  2. It then calls the default constructor for class Screen to initialize the object
  3. It then initializes ps with the address of the Screen object
what if the step 2 throws an exception, we hvae to ensure the memory is not leaked, the class designer can provide a overload delete() operator in this situation. 

If the class designer provides an overload operator delete() with parameters with types that match the parameter type of operator new (), the implementation automatically calls this operator delete() to deallocate the storage, 

for example.

Screen * ps = new (Start) Screen;
 
if the default constructor for class Screen exists by throwing an exception, the implementation looks  for an operator delete() to be considered, it must have types that matches those of the new operator new() called. 

First parameter of the new operator and the first parameter of the delete operator are size_t and void * repsectivly. they are not considered for this comparision.


void operator delete(void *, Screen *)
 

 

 

If this operator is found under class Screen, it is called to deallocate the storage if the constructor called by the new expression throws an exception. If this operator delete is not found(), then no operator delete() is called. 

 

 

Let 's see the 

 

 

/**
* file 
*   Screen.h
*
*  description:
*   this is the header file definition of the screen and the ScreenPtr
*/

class Screen
{
public:
	void move(int x, int y);

	/** 
	* the placement new and delete operator
	*
	*/
	void *operator new(size_t );
	void *operator new(size_t, Screen*  );

	/** the placement delete operator 
	*
	*
	*/
	void operator delete(void *);
	void operator delete (void * , Screen *);

	Screen() { };
	Screen(Screen *) { throw "Screen(Screen *); ";}
private:
protected:
};
 

 

 

and below is the implementation code. 

 

 

/**
* file 
*   Screen.h
*
*  description:
*   this is the header file definition of the screen and the ScreenPtr
*/
#include "stdafx.h"
#include "Screen.h"
#include <iostream>
#include <exception>

using std::cout;
using std::endl;
using std::cerr;
using std::exception;

void * Screen::operator new(size_t size) { 
	cout << "void * Screen::opreator new (size_t size) " << endl;
	return ::new char[size];
}
void * Screen::operator new(size_t size, Screen* start) {
	cout << "void * Screen::operator new (size_t size, Screen* start) " << endl;
	if (start == NULL) // if you provide a placement new operator and the placement new operaor allocate memory, then you should provide a overloaded delete operator
	{
		throw new exception("bad argument - " "start");
	}
	return start;
}

void Screen::operator delete(void * ptr) 
{
	cout << "void Screen::operator delete(void* start) " << endl;
	::delete ptr;
}

void Screen::operator delete(void * ptr, Screen * start)
{
	cout << "void * Screen::operator delete (void * ptr, Screen* start) " << endl;
	// do nothing...
}
 

 

 

Below is the test code

 

 

 

/**
*  func(Screen* start) 
*/
// what is steps of the calls of Screen* ps =   new (start) Screen;
// 1. it calls the class operaor new (size_t, Screen *)
// 2. it then calls the default constructor for class Screen to initialize the object
// 3. it then initializes ps with the address of the Screen object
void func(Screen * start) 
{
	Screen* ps = new (start) Screen;
	delete ps; // it calles void Screen::operator delete(void * ptr) , not void Screen::operator delete(void * ptr, Screen start) 
}

void func2()
{
	Screen *ps = new Screen;
	delete ps; // it calls void Screen::operator delete(void * ptr) 
}


void func3(Screen * start) 
{
	try 
	{
		Screen *ps = new (start) Screen(start);
		delete ps; // this is never reached.
	}
	catch (const char *) {
		// you will probably see the "void Screen::operator delete(void * ptr, Screen * start)" called.
	}
}

void func4()
{
	try 
	{
		Screen *ps = new Screen(NULL);
		delete ps; // this line of code is never reached.
	}
	catch (const char *) 
	{
		// you will probably see the "void Screen::operator delete(void * ptr)" called.
	}
}        int _tmain(int argc, _TCHAR* argv[])
{
	//test_use_of_ptr_overload();
	Screen * screen  = new Screen();
	func(screen);
	func2();
	screen = new Screen();
	func3(screen);
	delete screen;
	func4();
	return 0;
}
 

 

and the output is like this: 

 

 

 

void * Screen::opreator new (size_t size)
void * Screen::operator new (size_t size, Screen* start)
void Screen::operator delete(void* start)
void * Screen::opreator new (size_t size)
void Screen::operator delete(void* start)
void * Screen::opreator new (size_t size)
void * Screen::operator new (size_t size, Screen* start)
void * Screen::operator delete (void * ptr, Screen* start)
void Screen::operator delete(void* start)
void * Screen::opreator new (size_t size)
void Screen::operator delete(void* start)
 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值