`

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

    博客分类:
  • c++
 
阅读更多

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)
 

 

 

 

分享到:
评论

相关推荐

    全面解析C++中的new,operator new与placement new

    new operator/delete operator就是new和delete操作符,而operator new/operator delete是函数。 new operator(1)调用operator new分配足够的空间,并调用相关对象的构造函数(2)不可以被重载 operator new(1)只...

    c语言中new_C++的new归纳详解

    本文详细介绍了 C++ 中的 new,包括 new operator、operator new、placement new 三种形态的内容,并且详细解释了每一种形态的行为和用法,同时也提到了 delete 的相关知识点,希望对读者有所帮助。

    placement new详解

    placement new的引入,为C++程序员提供了一种更灵活、更高效的对象构造机制,尤其在需要优化内存管理或提升执行效率的场景下,它发挥着重要作用。然而,使用placement new也意味着程序员需要更加注意内存管理和资源...

    C++_new_operator详解

    通过上述分析可以看出,`new`操作符及其相关的`operator new`和`placement new`在C++中扮演着重要角色。它们提供了灵活的内存管理机制,但也要求程序员正确地管理和释放内存,以避免内存泄漏和其他潜在的问题。理解...

    关于new和delete的详细用法

    2. new的三种形态:new operator、operator new、placement new。new operator是我们平时所使用的new,其行为就是前面所说的三个步骤。operator new是可以重载的,用于分配内存。placement new是用来实现定位构造的...

    深入C++的new关键字

    new可以分为三种形态:new operator、operator new、placement new。new operator是我们平时所使用的new,其行为就是前面所说的三个步骤。operator new是可以重载的,用于分配内存的操作符。placement new是用来实现...

    总结C++中三种关于new的使用方法.docx

    new 在 C++ 中有三种使用方法:new 表达式、operator new 和 placement new。每种方法都有其特点和应用场景,程序员需要根据实际情况选择合适的方法来使用 new。同时,delete 语句也需要根据实际情况选择合适的方法...

    c++中new的三种用法详细解析

    使用`placement new`构造的对象,必须显式地调用析构函数来释放,而不能使用`delete`,因为`delete`不会正确地处理这种情况。 在实际编程中,理解这些不同的`new`用法可以帮助你更好地管理内存,防止内存泄漏,并...

    C++new运算符[参考].pdf

    C++ new 运算符的含义可以分为三种:new 运算符、new 函数和 placement new。每种含义都有其特点和用法。 new 运算符 new 运算符是 C++ 中最常用的 new,它作为运算符,用于在堆上分配一块内存,并自动调用类的...

    深入C++基础_new运算符.doc

    `new`操作符在C++中扮演着重要角色,它不仅提供了动态内存分配的能力,还允许开发者通过重载`operator new`和`placement new`等方式来定制内存管理和对象构造的过程。掌握这些细节有助于编写更加高效和安全的C++程序...

    cpp代码-只能创建栈对象 做法:将operator new/delete设置为私有的

    首先,`operator new`和`operator delete`是C++中的全局运算符,用于动态内存分配和释放。当我们将它们声明为类的私有成员时,外部代码就无法直接通过`new`关键字在堆上创建该类的对象。这是因为私有成员函数只能在...

    总结C++中三种关于new的使用方法.pdf

    在C++编程语言中,`new`关键字有三种主要的使用方法,这些方法可以被归类为两大类:new表达式和new操作符。每种用法都有其特定的用途和场景,对于理解和掌握C++内存管理至关重要。 首先,我们来看最常用的**new...

    c语言newC++的new[收集].pdf

    5. **`operator new` 和 `operator delete` 重载** - 如果重载了 `operator new`,为了保持一致性,通常也需要重载 `operator delete`,以便在释放内存时执行自定义操作。 6. **`placement new` 示例** - 使用 `...

    C++操作符重载手册

    本手册将详细阐述C++中操作符重载的相关规则、建议以及如何重载`operator new`。 **一、操作符重载规则** 1. **可重载的操作符** 包括基本的算术运算符(`+ - * / % ^ & | ~ !`),比较运算符(`&lt; &gt; &lt;= &gt;= == !=`...

    Effective C++(第三版)

    use the same form in corresponding uses of new and delete. 条款17:以独立语句将newed对象置入智能指针 store newed objects in smart pointers in standalone statements. 4. 设计与声明 designs and ...

    《深度探索C++对象模型》(Stanley B·Lippman[美] 著,侯捷 译)

    Placement Operator new的语意 6.3 临时性对象(Temporary Objects) 临时性对象的迷思(神话、传说) 第7章 站在对象模型的类端(On the Cusp of the Object Model) 7.1 Template Template的“具现”行为...

    浅析C++ new的三种面貌

    然而,`new`并非单一的操作,它实际上涉及到三个相关的概念,即`new operator`、`operator new()`和`placement new()`。理解这三种“面貌”的差异和用途对于编写高效且内存管理正确的C++代码至关重要。 首先,`new ...

    重载new 用法例子

    1. **重载的语法**:在C++中,你可以通过在类的作用域或全局作用域内定义`operator new`和`operator delete`函数来实现`new`的重载。例如: ```cpp void* operator new(size_t size) { // 自定义内存分配逻辑 } ...

Global site tag (gtag.js) - Google Analytics