描述:
有这样一个类:
CMyClass()
{
...
IMember *pMember;
...
virtual ~CMyClass();
CMyClass(IMember *p); // CMyClass的创建需要一个IMember指针,该IMember对象已经创建,传入一个有效的*p
}
在构造函数中
CMyClass(IMember *p)
{
pMember = p; // 经过这个赋值,p的引用计数是不是+1了?
...
}
在析构函数中:
~CMyClass()
{
if(pMember)
{
// 问题在这里,如果上面pMember=p增加了引用计数,这里是该这样释放以减少引用计数么?
pMember->Release();
pMember = NULL;}
}
按我的理解好像是要这样做的,但偏偏这样做会出现“访问冲突”,去掉Release这一段就没问题了,不解,请大家指教。
《COM本质论》中有这样讲:
调用AddRef:
A1. 将非空指针写局部变量中;A2. 被调用方把一个非空指针写到方法输出参数中;
A3. 被调用方返回一个非空指针;
A4. 把一个非空指针写到对象的数据成员中.
调用Release
R1. 改写一个非局部变量或数据成员之前;
R2. 离开非空局部变量的作用域之前;
R3. 被调用方改写方法的参数,且参数为非空;
R4. 改写一个对象的非空数据成员之前;
R5. 在离开一个对象的析构函数之前, 并且这时还有一个非空接口接口指针作为数据成员.
解决方案1:
CMyClass(IMember *p)
{
pMember = p; // 经过这个赋值,p的引用计数是不是+1了?
...
}
不会+1 除非你显示的调用AddRef
建议你用CComPtr来封装这些COM指针, 这样你就不用考虑这个问题了
构造的时候没有+1
析构的时候 有-1
收支不平衡
你需要自己实现AddRef等来实现计数,同时第一次调用应该是new一个对象,以后使用QueryInterface,都是传递new的指针,同时AddRef计数
当你Release的时候,判断是不是计数为0了,为0了,就delete释放·
构造函数中应该调用接口的AddRef