是这样的:class A
{
....
};class B
{
A *pB_A;
....
};class C
{
A *pC_A;
....
};.........如何对pB_A和pC_A进行判断?(假设在此之前以对pB_A和pC_A赋值,然后单独释放了它们所指向的对象)
{
....
};class B
{
A *pB_A;
....
};class C
{
A *pC_A;
....
};.........如何对pB_A和pC_A进行判断?(假设在此之前以对pB_A和pC_A赋值,然后单独释放了它们所指向的对象)
方式很多,要么用全局变量、要么再class A 里加个链表记住都有谁指向自己了。
如果我在class A 里加个链表记住都有谁指向自己,当释放class A时,将链表中的指针都恢复为空。但是,如果class B或class C先释放呢?
C(){nRef=1;};
int AddRef(){
return ++nRef;
}
int Release(){
if(!--nRef)
{
delete this;
return 0;
}
return nRef;
}
protected:
virtual~c()//donot allow delete from outsides
{}
int nRef;};
struct a{
a(c* pc)
{
m_pc=pc;
pc->AddRef();
}void do_Sth(){
;//...使用完成m_pc了
m_pc->Release();
m_pv=NULL;
}protected:
c* m_pc;
}
class b的结构和a也差不多,就不写了
下面是main函数:
void main()
{
c* pc=new c;
a clsA(pc);
b clsB(pc);
pc->Release();//ok pc was hold by both clsA and clsB,so we don't need it.release.
pc=NULL;
a.do_sth();
b.do_sth();;//should no memory leak
}
这个方面的问题我专门写了一篇文章,过几天放上来。
你的方法类似于COM的引用计数的方法,这种方法在有被引用的情况下对象不能释放。 我想找一种方法:当class A的对象自己释放时,不用遍历引用自己的对象,而引用它的对象又能够判断它已被释放的简单方法。
《C++ Without Memory Errors》by Dejan Jelović
http://www.jelovic.com/articles/cpp_without_memory_errors_slides.htm
其中有个工具,就叫工具吧,很多时候都可以使用,这可是秘密武器。
struct A{
....
};struct B{
B(A* pa){m_rpa=pa;}
protected:
A*& m_rpa;
};struct C{
C(A* pa){m_rpa=pa;}
protected:
A*& m_rpa;
};
void main()
{
A* pa=new A;
B b(pa);
C c(pa);
delete pa;
pa=NULL;//b,c可以根据m_rpa的值来判断pa是否有效;
}
把握!
example:
CYourObject * lpYourObject1 = new CYourObject;
CYourOjcet * lpYourObject2 = lpYourObject1;
delete lpYourObject1; // 这时 lpYourObject2 还是指向原来的内存地址 ,编译
//器并不会把 lpYourOjbect2 付值 为 NULL . 所有说 一个指针是不是有效是程序员的
// 事情
BOOL AfxIsValidAddress( const void* lp, UINT nBytes, BOOL bReadWrite = TRUE );
第一个值是你的指针!第二个是对象的大小!第三个是说明你要判断这块的地址是可读写(TRUE〕的还是只读的(FASLE〕;
SDK中也有类似的函数如
BOOL IsBadCodePtr(
FARPROC lpfn // address of function
);
BOOL IsBadReadPtr(
CONST VOID *lp, // address of memory block
UINT ucb // size of block
);BOOL IsBadStringPtr(
LPCTSTR lpsz, // address of string
UINT ucchMax // maximum size of string
);
BOOL IsBadWritePtr(
LPVOID lp, // address of memory block
UINT ucb // size of block
);
等