请教个C++中继承的有关问题
请问个C++中继承的问题
请看:
class IUn
{
public:
virtual void QueryInterface(int iid,void **pObj)=0;
virtual void AddRef()=0;
virtual void Release()=0;
};
class IA:public IUn
{
public:
virtual void dspa()=0;
};
class IB:public IUn
{
public:
virtual void dspb()=0;
};
class C:public IA,public IB
{
private:
int ref;//计数
public:
C();
public:
virtual void QueryInterface(int iid,void **pObj);
virtual void AddRef();
virtual void Release();
virtual void dspa();
virtual void dspb();
};
C::C()
{
ref=0;
}
void C::QueryInterface(int iid,void **pObj)
{
switch(iid)
{
case 1:
case 2:*pObj=(IA*)this;((IA*)(*pObj))->AddRef();break;
case 3:*pObj=(IB*)this;((IB*)(*pObj))->AddRef();break;
}
}
void C::AddRef()
{
ref++;
}
void C::Release()
{
ref--;
if(ref==0)
delete this;
}
void C::dspa()
{
printf("Display Class A\n");
}
void C::dspb()
{
printf("dsiplay Class B\n");
}
这是我看用C++写的COM组件,发现类C中有两份IUn,可是在实现时,只实现了IUn中的
QueryInterface()、AddRef()、Release()一次,我想知道是不是两份的函数共享了
这份代码?可是两份函数的地址应该不一样吧,为什么可以这样呢?能详细说说理由吗?
------解决方案--------------------
楼主搜一下虚继承,菱形继承。说的就是你这种情况。
------解决方案--------------------
他们共享IUn,因为采用的是虚继承,会根据继承顺序,去构造IA然后构造IA的基类IUn,然后去构造IB,因为是虚继承的缘故,不会去构造IB的基类,它会和IA共享一份IUn的数据
------解决方案--------------------
这样调用的时候,发现是同一个this地址,那应该说明是调用了同一个地方
------解决方案--------------------


建议LZ看下这本书<c++反汇编与逆向分析技术揭秘>
http://www.vdisk.cn/achongvideonote?tag=ALLFILES&p=2
这儿有此书相对应的视频教程,讲得比较细,你提的问题能找到答案
请看:
class IUn
{
public:
virtual void QueryInterface(int iid,void **pObj)=0;
virtual void AddRef()=0;
virtual void Release()=0;
};
class IA:public IUn
{
public:
virtual void dspa()=0;
};
class IB:public IUn
{
public:
virtual void dspb()=0;
};
class C:public IA,public IB
{
private:
int ref;//计数
public:
C();
public:
virtual void QueryInterface(int iid,void **pObj);
virtual void AddRef();
virtual void Release();
virtual void dspa();
virtual void dspb();
};
C::C()
{
ref=0;
}
void C::QueryInterface(int iid,void **pObj)
{
switch(iid)
{
case 1:
case 2:*pObj=(IA*)this;((IA*)(*pObj))->AddRef();break;
case 3:*pObj=(IB*)this;((IB*)(*pObj))->AddRef();break;
}
}
void C::AddRef()
{
ref++;
}
void C::Release()
{
ref--;
if(ref==0)
delete this;
}
void C::dspa()
{
printf("Display Class A\n");
}
void C::dspb()
{
printf("dsiplay Class B\n");
}
这是我看用C++写的COM组件,发现类C中有两份IUn,可是在实现时,只实现了IUn中的
QueryInterface()、AddRef()、Release()一次,我想知道是不是两份的函数共享了
这份代码?可是两份函数的地址应该不一样吧,为什么可以这样呢?能详细说说理由吗?
------解决方案--------------------
楼主搜一下虚继承,菱形继承。说的就是你这种情况。
------解决方案--------------------
他们共享IUn,因为采用的是虚继承,会根据继承顺序,去构造IA然后构造IA的基类IUn,然后去构造IB,因为是虚继承的缘故,不会去构造IB的基类,它会和IA共享一份IUn的数据
------解决方案--------------------
void C::AddRef()
{
printf("0x%x\n",this);
ref++;
}
C obja;
void *pVoid;
obja.QueryInterface(2,&pVoid);
obja.QueryInterface(3,&pVoid);
这样调用的时候,发现是同一个this地址,那应该说明是调用了同一个地方
------解决方案--------------------
#include "stdafx.h"
#include "stdio.h"
// 菱形结构分析
// 定义家具类,等同于类A
class CFurniture{
public:
CFurniture(){
m_nPrice = 0;
}
virtual ~CFurniture(){ // 家具类虚析构函数
printf("virtual ~CFurniture()\r\n");
}
virtual int GetPrice(){ // 获取家具价格
return m_nPrice;
};
protected:
int m_nPrice; // 家具类成员变量
};
// 定义沙发类,继承自CFurniture,等同与类B
class CSofa : virtual public CFurniture{
public:
CSofa(){
m_nPrice = 1;
m_nColor = 2;
}
virtual ~CSofa(){ // 沙发类虚析构函数
printf("virtual ~CSofa()\r\n");
}
virtual int GetColor(){ // 获取沙发颜色
return m_nColor;
}
virtual int SitDown(){ // 沙发可以坐下休息
return printf("Sit down and rest your legs\r\n");
}
protected:
int m_nColor; // 沙发类成员变量
};
// 定义床类,继承自CFurniture,等同与类C
class CBed : virtual public CFurniture{
public:
CBed(){
m_nPrice = 3;
m_nLength = 4;
m_nWidth = 5;
}
virtual ~CBed(){ // 床类虚析构函数
printf("virtual ~CBed()\r\n");
}
virtual int GetArea(){ // 获取床面积
return m_nLength * m_nWidth;
}
virtual int Sleep(){ // 床可以用来睡觉
return printf("go to sleep\r\n");
}
protected:
int m_nLength; // 床类成员变量
int m_nWidth;
};
// 子类沙发床定义,派生自CSofa、CBed类,等同与类D
class CSofaBed : public CSofa, public CBed{
public:
CSofaBed(){
m_nHeight = 6;
}
virtual ~CSofaBed(){ // 沙发床类虚析构函数
printf("virtual ~CSofaBed()\r\n");
}
virtual int SitDown(){ // 沙发可以坐下休息
return printf("Sit down on the sofa bed\r\n");
}
virtual int Sleep(){ // 床可以用来睡觉
return printf("go to sleep on the sofa bed\r\n");
}
virtual int GetHeight(){
return m_nHeight;
}
protected:
int m_nHeight; // 沙发类成员变量
};
void main(int argc, char* argv[])
{
// 菱形结构
CSofaBed SofaBed;
CFurniture * pFurniture = &SofaBed;
CSofa * pSofa = &SofaBed;
CBed * pBed = &SofaBed;
}
建议LZ看下这本书<c++反汇编与逆向分析技术揭秘>
http://www.vdisk.cn/achongvideonote?tag=ALLFILES&p=2
这儿有此书相对应的视频教程,讲得比较细,你提的问题能找到答案