★★★ 200分总结mfc下的多重继承 ★★★ 有点困惑,还望大家畅所欲言啦~~ 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我也一样,MFC对多继承支持不好,尤其是使用了DECLARE_DNYCREATE之后 另外多重继承也是将COM接口结合到COM对象中基本方法之一,可以实现在一个COM对象中实现多个接口. 以下是个人的理解:在BCB中就有多重继承,在MFC中为了简化C++中的难度所以没有用到多生继承。多重继承是子类和父类如网状结构、简单继承如树型结构。 ATL中倒是常用到,其它的基本上没用到过 1.MFC不支持多继承(可以通过嵌套技术来模拟多继承)。class A { public: class B{ public: class C{}; };};2.多继承非常有用(ATL,WTL大量使用,我感觉非常有用!)3.代码更加简洁,易读。... 1、MFC没有接触过多重继承2、C++中学习过 to caslwzgks(梦想家) ,你所说的嵌套技术指的是MFC对COM的支持吧,MFC为了消除多重继承(MI)带来接口的混乱,从而采用了嵌套继承的方法。而正如你所说,ATL,WTL中大量使用了MI,可见MI的正面效应。bm1408(VC一线) ,MFC的确不是为MI所设计的,但这并不意味着用户不能在MFC应用程序中使用MI。所以,若要在MFC中使用MI,一方面要遵循MFC的要求,另一方面还要遵循C++的规范。---------------------------------------------------------------下面是我参照了资料的总结,请大家批评补充。---------------------------------------------------------------1.CObject::IsKindOf函数对于使用MI的类来说就不能正确识别它的类型了,原因很简单,它父类有多个,这个函数无法确定了。用户确一定要保证在使用MI时,如果使用到了Cobject,一定要把它放在继承类的最左边。2.必须重新实现那些有二义性的函数。 让我们来看下面一个例子 class CListWnd : public CFrameWnd, public CObList { ... }; CListWnd myListWnd; 上面的情况中,Cobject被包括了两次,这导致了两个问题: 一.对Cobject成员函数的调用必须是无二义的。 myListWnd.Dump(afxDump); //这里会有一个编译错误,编译器不明白你调用的究竟是哪一个类 的Dump,是CFrameWnd::Dump还是CObList::Dump? 二.对静态成员函数包括'operator new'和'operator delete'的调用必须是无二义的。 这种情况编译器经常提醒你构造函数的位置,new和delete有二义性。所以,在上面的情况中,必须重新实现那些有二义性的函数,例如下面的代码class CListWnd : public CFrameWnd, public CObList{public:void* operator new(size_t nSize) { return CFrameWnd::operator new(nSize); } //调用的是CframeWnd中的newvoid operator delete(void* p) { CFrameWnd::operator delete(p); } //调用的是CframeWnd中的deletevoid Dump(CDumpContent& dc) { CFrameWnd::Dump(dc);CObList::Dump(dc); }注意:使用虚继承并不能消除这种二义性。3.运行(runtime)类型机制支持一些宏:DECLARE_DYNAMIC,IMPLEMENT_DYNAMIC,DECLARE_DYNCREATE,IMPLEMENT_DYNCREATE,DECLARE_SERIAL和IMPLEMENT_SERIAL,这些宏在单继承的时候工作得不错,可是对于多继承,出现在IMPLEMENT_DYNAMIC或IMPLEMENT_SERIAL中的必须是在继承关系最左边的基类。其中,对于消息映射有两项要求: 一.基类中只能有一个Wnd的导出类; 错误例子: class CTwoWindows : public CFrameWnd, public CEdit { ... }; // 两个CWnd复本 二.这个导出类必须在继承关系的最左边. 错误例子: class CListEdit : public CObList, public CEdit { ... }; // Cedit(由CWnd导出)必须在最左边 在多重继承下,要注意可以产生一些"切片"slicing",还有什么虚函数,纯虚函数等等... 求给个思路,设计性问题 线程单独处理图片处理算法的错误 希望高手帮忙!!我想完成程序的日志读写.我改80分,谢谢高手帮忙! 如何连续读入多个BMP文件到内存以便进行整体处理? 500分求Quick ‘n Easy FTP Server的源程序 如何用http上传一个文件 请教关于编CSocket的一些简单的问题!!谢谢!! wininet编程问题,愚蠢问题 请教关于smartphone AP开发时的control问题 有谁有《windows程序设计》(第五版)的电子书籍(发到邮箱即给分50) 写一个Filter! 字符转换问题?如何把“字母+汉字+数字”字符串转换成Unicode 字符?
在BCB中就有多重继承,在MFC中为了简化C++中的难度所以没有用到多生继承。
多重继承是子类和父类如网状结构、简单继承如树型结构。
public:
class B{
public:
class C{};
};
};2.多继承非常有用(ATL,WTL大量使用,我感觉非常有用!)3.代码更加简洁,易读。...
2、C++中学习过
你所说的嵌套技术指的是MFC对COM的支持吧,MFC为了消除多重继承(MI)带来接口的混乱,从而采用了嵌套继承的方法。而正如你所说,ATL,WTL中大量使用了MI,可见MI的正面效应。
bm1408(VC一线) ,
MFC的确不是为MI所设计的,但这并不意味着用户不能在MFC应用程序中使用MI。所以,若要在MFC中使用MI,一方面要遵循MFC的要求,另一方面还要遵循C++的规范。---------------------------------------------------------------
下面是我参照了资料的总结,请大家批评补充。
---------------------------------------------------------------
1.CObject::IsKindOf函数对于使用MI的类来说就不能正确识别它的类型了,原因很简单,它父类有多个,这个函数无法确定了。用户确一定要保证在使用MI时,如果使用到了Cobject,一定要把它放在继承类的最左边。2.必须重新实现那些有二义性的函数。
让我们来看下面一个例子
class CListWnd : public CFrameWnd, public CObList
{
...
};
CListWnd myListWnd; 上面的情况中,Cobject被包括了两次,这导致了两个问题: 一.对Cobject成员函数的调用必须是无二义的。
myListWnd.Dump(afxDump); //这里会有一个编译错误,编译器不明白你调用的究竟是哪一个类 的Dump,是CFrameWnd::Dump还是CObList::Dump?
二.对静态成员函数包括'operator new'和'operator delete'的调用必须是无二义的。 这种情况编译器经常提醒你构造函数的位置,new和delete有二义性。所以,在上面的情况中,必须重新实现那些有二义性的函数,例如下面的代码class CListWnd : public CFrameWnd, public CObList
{
public:
void* operator new(size_t nSize) { return CFrameWnd::operator new(nSize); } //调用的是CframeWnd中的newvoid operator delete(void* p) { CFrameWnd::operator delete(p); } //调用的是CframeWnd中的deletevoid Dump(CDumpContent& dc) { CFrameWnd::Dump(dc);CObList::Dump(dc); }注意:使用虚继承并不能消除这种二义性。3.运行(runtime)类型机制支持一些宏:DECLARE_DYNAMIC,IMPLEMENT_DYNAMIC,DECLARE_DYNCREATE,IMPLEMENT_DYNCREATE,DECLARE_SERIAL和IMPLEMENT_SERIAL,这些宏在单继承的时候工作得不错,可是对于多继承,出现在IMPLEMENT_DYNAMIC或IMPLEMENT_SERIAL中的必须是在继承关系最左边的基类。其中,对于消息映射有两项要求: 一.基类中只能有一个Wnd的导出类;
错误例子:
class CTwoWindows : public CFrameWnd, public CEdit
{ ... }; // 两个CWnd复本
二.这个导出类必须在继承关系的最左边.
错误例子:
class CListEdit : public CObList, public CEdit
{ ... }; // Cedit(由CWnd导出)必须在最左边