#include <iostream>
using namespace std;
/*判斷某個對象是否在heap*/
class A{
public:
A() ;
class NoOnHeap;
A(int ) { }
static void* operator new(size_t size);
void destroy() { delete this;}
protected: //for B
static bool isOnHeap;
~A() { }//defined must be
};
bool isOnHeap = false;
A::A()
{
if(!isOnHeap)
throw NoOnHeap();
else
A(int);//一個正常的ctor,new不是正常的
isOnHeap = false;
}
void* operator new(size_t size)
{
isOnHeap = true;
return ::operator new(size);
}
/*不行的原因:判斷位在有些情況下不能預期工作
1 operator new[],new是分配一塊內存,ctor來賦值
所以就算你有記得把判斷位重置也沒用,因爲它就用一次new
2 A* pa = new(*new A) 理想狀態下是 new - ctor - new - ctor
但實際上是 new new ctor ctor
*/
bool onHeap(const void* address)
{
char onStack;
return address < &onStack;
}
/*安妮他們在函數作用域中出現的次序來分配他們在棧中位置、但考慮static
一切就不對了,當想盡辦法去加上if static的方法時,又要考慮不可移植,這時候
就要重新考慮是不是判斷是否在堆中就是一個錯誤的思想,書上說,一般上client
都是想delete安全指針。但值得注意的是,delete this聲名狼藉*/
/*且是否安全得delete 指針 與 是否在堆上並沒有關係*/
void main()
{
C* c = new C;
delete c;
//哦哦,他把 A* vaule ==> A vaule 這樣就是爲了讓它沒有析構函數調用
}
class HeapTracked//足跡
{
public:
HeapTracked();
class missAddress;//用以拋出
virtual ~HeapTracked() = 0;
static void* operator new (size_t size);
static void operator delete (void *ptr);
bool isOnHeap();
private:
typedef const void* rawMemory;
list<rawMemory> addresses;
};
void * HeapTracked::operator new (size_t size)
{
void* address = ::operator new(size);
addresses.push_front();//頭部?
return address;address
}
void HeapTracked::operator delete(void *ptr)
{
list<rawMemory>::const_iterator it =
find(addresses.begin(), addresses.end(), ptr);
if(it != addresses.end())
{ addresses.erase(it);
::operator delete ptr;
}
else
{
throw missAddress();
}
}
bool HeapTracked::isOnHeap()
{
const void * rawAddress = dynamic_cast<const void*>(this);
//取得一個指針,指向 *this 所佔內存的起始處,我想不到的一部
list<rawMemory>::iterator it =
find(addresses.begin(), addresses.end(), rawAddress);
return it != addresses.end();
}
item26判斷對象是否在堆中
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.