1. 程式人生 > >過載operator new和 operator delete

過載operator new和 operator delete

 1.建立類Foo

    在類Foo中過載operator new和 operator delete。

class Foo
{
private:
	int _id;
public:
	Foo() :_id(0)
	{  
		cout << "Default Construct " << this  << " id = " << _id << endl;
	}
	Foo(int id) :_id(id)
	{ 
		cout << "Construct " << this << " id = " << _id << endl;
	}
	~Foo()
	{  
		cout << "Destructor " << this << endl; 
	}
	static void *operator new (size_t size)
	{
		Foo *p = (Foo*)malloc(size);
		return p;
	}
	static void operator delete(void *p, size_t size)
	{
		free(p);
	}
	static void *operator new[](size_t size)
	{
		Foo *p = (Foo*)malloc(size);
		return p;
	}
    static void operator delete[](void *p, size_t size)
	{
		free(p);
	}	
};

2.測試程式

int main()
{
	cout << "sizeof(Foo) = " << sizeof(Foo) << endl;
	Foo *p = new Foo();
	delete p;

	Foo *pArray = new Foo[5];
	delete[]pArray;

	system("pause");
}

3.執行結果

 

4.結果分析

    類Foo的大小是4,原因是包含int型別的資料_id。

    過載operator new和 operator delete時,接管了記憶體的申請和釋放,此處簡單的呼叫malloc和free,以後可能通過記憶體池管理記憶體,提高效率。

    Foo *p = new Foo()中,呼叫*operator new時傳入的size為4。

    Foo *pArray = new Foo[5]中,呼叫*operator new[]時傳入的size為24。

    對陣列而言,析構的順序和構造的順序相反。

5.擴充套件

    operator new的過載版本可以有多個引數,但第一個引數必須是size_t。

static void *operator new (size_t size, void* start)
{
  return start;
}
static void *operator new (size_t size, long extra)
{
  return malloc(size + extra);
}
static void *operator new (size_t size, long extra, char init)
{
  return malloc(size + extra);
}

    operator delete也可以有多個過載版本,但只有當new所呼叫的建構函式丟擲異常,才會呼叫這些過載版本。即使operator delete未能一一對應於operator new,也不會出現任何報錯,只是意味著放棄處理建構函式丟擲的異常。

static void operator delete(void *, void *)
{
}
static void operator delete(void *, long)
{
}
static void operator delete(void *, long, char)
{
}

    標準庫中,string類已提供的placement new(size_t size, long extra)的過載形式。