c++ 类的多态
来源:互联网 发布:json里面含有html标签 编辑:程序博客网 时间:2024/04/29 16:20
1. 何为多态
多态(polymorphisn),即多种不同的形态。在c++中,指一般的函数或类的接口,在运行时,因为外部的因素变化,执行不同的过程,产生不同的结果。
(1) 编译时绑定。
这是函数重载实现多态的情况。多个函数有相同的名字,不过参数和返回值不同,在编译时函数名称和调用地址就已经确定。运行时,依据函数名和参数确定调用哪个接口。
(2) 运行时绑定
这是类的接口实现多态的情况。基类和子类中的接口名称和参数完全一致,编译时接口的名称和调用地址的关系并不确定,运行时,依据类的具体类型来确定调用哪个接口。
后面仅对类实现多态的情况进行解析
2. 多态的作用
(1). 通过一个接口,实现不同的功能。
定义基类的接口为虚函数,子类继承此接口,并各自实现此接口。指向子类的基类指针,执行基类的接口调用,便可以调用子类的接口实现实现,不用太多改变,就可以进行 功能的扩展。
譬如对于游戏的后端而言,在一个处理逻辑的主循环中,一个基类的指针顺序调用其三个接口 on_init(),on_active(),on_finish(),通过传入不同的子类指针,就可以调用实现不同的功能。
要进行功能扩展时,只需要实现一个child继承至base,并实现on_init, on_active,on_finish,并注册一个的消息ID与此类关联即可。
class base {public:virtual on_init();virtual on_active();virtual on_finish();};class child_1:public base(){public:virtual on_init();virtual on_active();virtual on_finish();};class child_2:public base(){public:virtual on_init();virtual on_active();virtual on_finish();};base* p = NULL;// 待处理的消息// 设置两个消息,1、2// 分别对应child_1的处理和child_2的处理vector<int> msg;msg.push_back(1);msg.push_back(2);int msg_count = msg.size();// 消息ID和处理类的关联map<int, base*> msg_child;// 注册消息ID与处理类的关联msg_child.insert(make_pair(1, new child_1()));msg_child.insert(make_pair(2, new child_2()));map<int, base*>::iterator it;while(msg_count--){// 消息与对应的处理类it = msg_child.find(msg[msg_count]);....p = it->second;// 子类的处理过程if(p){p->on_init();...p->on_active();...p->on_finish();...}...}
3. 多态的实现
c++类的多态,通过如下方式来实现:
(1)定义一个基类,并声明某个接口为虚函数,用 virtual 修饰。
(2)定义一个子类,public 继承此基类,并重新实现基类中的虚函数接口,参数、返回值必须一致。
(3)定义一个基类的指针,赋予基类或子类的值,调用声明为虚函数的接口(或通过引用)。
一个技术点
基类中声明为虚函数的接口,子类中此接口自动为虚函数,无需显示声明。基类及其子类以及子类的子类的这个接口,都将具有多态性。
#include <stdlib.h>#include <iostream>using namespace std;class fruit{public:virtual void name(){cout << "----fruit----" << endl;}};class orange:public fruit{public:void name(){cout << "----orange----" << endl;}};class orange_yichang:public orange{public:void name(){cout << "----orange_yichang----" << endl;}};int main(int argc, char **argv){fruit FRUIT;orange ORANGE;orange_yichang ORANGE_YICHANG;fruit *test = NULL;orange *orange_test = NULL;test = &FRUIT;test->name();test = &ORANGE;test->name();test = &ORANGE_YICHANG;test->name();orange_test = &ORANGE_YICHANG;orange_test->name();return 0;}
上例中,基类 fruit,接口 name 声明为虚函数。子类 orange 继承至 fruit,orange_yichang 继承至orange。
执行结果如下。可见,虽然子类 orange 的接口 name 未显示声明为虚函数,但 orange_yichang 的 name 接口也具有多态行。
4. 多态的几个实现要点,不满足时的验证。
(1)接口未声明为虚函数。
#include <stdlib.h>#include <iostream>using namespace std;class fruit{public:void name(){cout << "------class fruit-------" << endl; }};class orange:public fruit{public:void name(){cout << "------class orange-------" << endl; }};int main(int argc, char **argv){fruit FRUIT;orange ORANGE;fruit *test = NULL;test = &FRUIT;cout << "Point to Fruit";test->name();test = &ORANGE;cout << "Point to Orange"; test->name();return 0;}
执行结果如下。可见虽然基类指针指向的是不同的对象,但调用的接口并没有多态性,都只调用了基类的接口。
(2)非 public 继承
#include <stdlib.h>#include <iostream>using namespace std;class fruit{public:void name(){cout << "------class fruit-------" << endl; }};class orange: private fruit{public:void name(){cout << "------class orange-------" << endl; }};int main(int argc, char **argv){fruit FRUIT;orange ORANGE;fruit *test = NULL;test = &FRUIT;cout << "Point to Fruit";test->name();test = &ORANGE;cout << "Point to Orange";test->name();return 0;}
编译时的错误如下。由于采用了private继承的方式,基类的所有成员和接口转为private的类型。子类的实例化对象,无法访问基类对象,所以无法进行指针的转换。
(3)定义子类的指针,将基类和子类的指针赋予它,调用动态接口
#include <stdlib.h>#include <iostream>using namespace std;class fruit{public:virtual void name(){cout << "------class fruit-------" << endl; }};class orange:public fruit{public:virtual void name(){cout << "------class orange-------" << endl; }};int main(int argc, char **argv){fruit FRUIT;orange ORANGE;orange *test = NULL;test = &FRUIT;cout << "Point to Fruit";test->name();test = &ORANGE;cout << "Point to Orange";test->name();return 0;}
编译结果如下。不能将基类对指针转换为子类指针,因为子类对象一般比基类对象要大,所以这种转换可能会造成访问越界,这大概是编译器报错的原因吧。
暂时更新到这,后续有新想法了再更新。
- C的多态
- C的多态
- 【C/C++】多态的概念
- [C++]多态的使用
- Objective-c的多态
- C++:类的多态与虚函数的使用
- OO in C(2): C语言的多态实现
- OO in C(2): C语言的多态实现
- OO in C(2): C语言的多态实现
- 多态的内幕--(C++, C)语言两个版本
- C/C++继承类的多态表现
- cpp (c++) 类的多态、继…
- 含有指针成员的类的拷贝[C/C++/C#]
- C++_对多态的理解
- C语言的多态实现
- C语言的多态实现
- C语言的多态实现
- C语言的多态实现
- GCC中常用的几个选项
- 理解MySQL——复制(Replication)
- [MySQL] - MySQL的Grant命令
- 通过show status 来优化MySQL数据库
- POJ-1330-earest Common Ancestors
- c++ 类的多态
- maven安装及项目搭建
- redis配置简介
- 浅析值类型与引用类型的内存分配[转载]http://blog.csdn.net/yuchen_0515/article/details/5330106
- 搞IT的技术人员为什么会如此苦逼
- Java多线程总结之 synchronized
- 物联网
- 看主线程如何等待子线程处理完毕
- Android操作系统默认图片