虚函数:(类的成员变量是虚函数) //
1 :编译多态的时候就确定了。函数长的都一样,参数不一样。在声明,定义的时候确定
2 运行多态:
是指针的话,指针可以改变指向,在编译的时候不能确定是父类对象,or 子类对象。
只有在运行的时候才能确定。
如果是父类指针既可以指向父类,也可以指向子类。
1 :通常的做法是,这样所有的子类都不用定义指向自己的指针,同时继承一个父类指针。继承一套struct。
所有的子类用父类的指针指向自己即可。
如:
struct CascadeHdlrEntry
{
CascadeHdlrTypeT type;
const char *pName;
CascadeBase *pHdlr;
};
//hdlrType是各种子类,如ResourceMgr,TaMgr,FileMgr etc
hdlrType = getMotherSignalHdlr(sigP->sigNo);
cascadeHdlrs[hdlrType].pHdlr->signalHandler(sigP);
如果没有case1的功能,则pHdlr需要根据hdlrType定义pHdlr1,pHdlr2,pHdlr3,etc
定义不同的子类指针指向不同的子类。但是有case1功能。这样就不用定义数组,所有的子类用一个struct。用一个基类指针。
如果采用pHdr1,2,3是c的变成风格。c也能实现这个多态功能.
用基类重载,run的时候根据赋值,确定是哪个子类,是resoucemgr,or tamgr or base etc。
具体见反例论证
cascadeHdlrs[hdlrType].pHdlr->signalHandler(sigP);
3: CascadeBase *pHdlr;
cascadeHdlrs[hdlrType].pHdlr->signalHandler(sigP);
不要看指针的定义,要看指针的指向。是父类or子类. 父类的指针只能指向父类定义,并且子类重载的函数。
如果是子类定义的函数,父类指针不能调用.
比如:
http://bbs.csdn.net/topics/390853050 中
//pb->Out(); //无法被调用
http://bbs.csdn.net/topics/390853050
==================================
2 第一个例子: 既可以指父类又指子类
cascadeHdlrs[CASCADE_NONE_HDLR].pHdlr = new CascadeBase;
cascadeHdlrs[CASCADE_FILE_HDLR].pHdlr = CascadeFileMgr::getInstance();
cascadeHdlrs[CASCADE_RESOURCE_HDLR].pHdlr = CscdResourceMgr::getInstance();
第二个例子:
run唯一。 不是唯一。
例子,实现了。
p1= cascaderm.getinstance();
p2=cascadeta.getinstance();
cascadeHdlrs[CASCADE_FILE_HDLR].pHdlr = p1 (p1 只需要是一个地址即可,如rm )
然后可以换成 cascadeHdlrs[CASCADE_FILE_HDLR].pHdlr = p2 (另一个地址即可,如ta)
和所有的指针用法一样。可以更换指向。
不是唯一性,仅仅是本项目不可以。
pHdlr= new Derive(); 会造成内存泄漏.可以不指向new的东西,指向new的东西更改方向会造成泄漏。指向指针变量则会随便更改。
1 :编译多态的时候就确定了。函数长的都一样,参数不一样。在声明,定义的时候确定
2 运行多态:
是指针的话,指针可以改变指向,在编译的时候不能确定是父类对象,or 子类对象。
只有在运行的时候才能确定。
如果是父类指针既可以指向父类,也可以指向子类。
1 :通常的做法是,这样所有的子类都不用定义指向自己的指针,同时继承一个父类指针。继承一套struct。
所有的子类用父类的指针指向自己即可。
如:
struct CascadeHdlrEntry
{
CascadeHdlrTypeT type;
const char *pName;
CascadeBase *pHdlr;
};
//hdlrType是各种子类,如ResourceMgr,TaMgr,FileMgr etc
hdlrType = getMotherSignalHdlr(sigP->sigNo);
cascadeHdlrs[hdlrType].pHdlr->signalHandler(sigP);
如果没有case1的功能,则pHdlr需要根据hdlrType定义pHdlr1,pHdlr2,pHdlr3,etc
定义不同的子类指针指向不同的子类。但是有case1功能。这样就不用定义数组,所有的子类用一个struct。用一个基类指针。
如果采用pHdr1,2,3是c的变成风格。c也能实现这个多态功能.
用基类重载,run的时候根据赋值,确定是哪个子类,是resoucemgr,or tamgr or base etc。
具体见反例论证
(QA:父类指针肯定可以指向子类。子类指针可以指向父类吗?
用派生类指针引用基类的对象。这种引用方式会导致语法错误。派生类指针必须先强制转换为基类指针,这种方法是不安全的。
http://blog.sina.com.cn/s/blog_3ce156ce01000af4.html
2: 虚函数指针: signalHandler是用的父类 or 子类的signHandler,当根据hdlrType知道了是哪个子类。子类根据虚函数表,确定用自己重写的函数。
具体见虚函数表.详见陈皓对虚函数表的论述。cascadeHdlrs[hdlrType].pHdlr->signalHandler(sigP);
3: CascadeBase *pHdlr;
cascadeHdlrs[hdlrType].pHdlr->signalHandler(sigP);
不要看指针的定义,要看指针的指向。是父类or子类. 父类的指针只能指向父类定义,并且子类重载的函数。
如果是子类定义的函数,父类指针不能调用.
比如:
http://bbs.csdn.net/topics/390853050 中
//pb->Out(); //无法被调用
notes: 中间删掉了自己对数组赋值是run的比较,删掉了3和cscade signal的比较。同时子类不能指向父类和父类不能调用子类non-virtual没有不计较,因为一个是类,一个函数level,没有可比性
===================================http://bbs.csdn.net/topics/390853050
虚函数表:关于子类重写virtual,则子类的函数放在第一个(本来是最后的变成第一个)是看什么书,得出的结论呢?
从blog上看是从vc的编译器看内存得出的结论。
==================================
反例论证:
1 是数组init不能 : cascadephlr[]={new(), resourcemgr.getinstance(),...}; // 既不能new,也不能getinstance。还是run状态
cascade[].phlr={...}; //这是一个指针,不是数组。run状态的数组,是loop。是n句执行命令。2 第一个例子: 既可以指父类又指子类
cascadeHdlrs[CASCADE_NONE_HDLR].pHdlr = new CascadeBase;
cascadeHdlrs[CASCADE_FILE_HDLR].pHdlr = CascadeFileMgr::getInstance();
cascadeHdlrs[CASCADE_RESOURCE_HDLR].pHdlr = CscdResourceMgr::getInstance();
第二个例子:
run唯一。 不是唯一。
例子,实现了。
p1= cascaderm.getinstance();
p2=cascadeta.getinstance();
cascadeHdlrs[CASCADE_FILE_HDLR].pHdlr = p1 (p1 只需要是一个地址即可,如rm )
然后可以换成 cascadeHdlrs[CASCADE_FILE_HDLR].pHdlr = p2 (另一个地址即可,如ta)
和所有的指针用法一样。可以更换指向。
不是唯一性,仅仅是本项目不可以。
pHdlr= new Derive(); 会造成内存泄漏.可以不指向new的东西,指向new的东西更改方向会造成泄漏。指向指针变量则会随便更改。