C++复习:纯虚函数和抽象类
纯虚函数和抽象类
1基本概念
2抽象类案例
3抽象类在多继承中的应用
C++中没有Java中的接口概念,抽象类可以模拟Java中的接口类。(接口和协议)
3.1有关多继承的说明
工程上的多继承
被实际开发经验抛弃的多继承
工程开发中真正意义上的多继承是几乎不被使用的
多重继承带来的代码复杂性远多于其带来的便利
多重继承对代码维护性上的影响是灾难性的
在设计方法上,任何多继承都可以用单继承代替
多继承中的二义性和多继承不能解决的问题
3.2多继承的应用场景
C++中是否有Java中的接口概念? |
绝大多数面向对象语言都不支持多继承 绝大多数面向对象语言都支持接口的概念 C++中没有接口的概念 C++中可以使用纯虚函数实现接口 接口类中只有函数原型定义,没有任何数据的定义。 class Interface { public: virtual void func1() = 0; virtual void func2(int i) = 0; virtual void func3(int i) = 0; }; |
实际工程经验证明 多重继承接口不会带来二义性和复杂性等问题 多重继承可以通过精心设计用单继承和接口来代替 接口类只是一个功能说明,而不是功能实现。 子类需要根据功能说明定义功能实现。 |
#include using
/* C++中没有接口的概念 C++中可以使用纯虚函数实现接口 接口类中只有函数原型定义,没有任何数据的定义。 */
class { public: virtual virtual };
class { public: virtual virtual virtual };
class { public: int a; }; class { public: void print() { cout << }
int add(int { return }
int minus(int { return } };
int main() { Child c;
c.print();
cout << c.add(3, 5) << endl; cout << c.minus(4, 6) << endl;
Interface1* i1 = &c; Interface2* i2 = &c;
cout << i1->add(7, 8) << endl; cout << i2->add(7, 8) << endl; system("pause"); } |
4抽象类知识点强化
/*
编写一个C++程序, 计算程序员( programmer )工资
1 要求能计算出初级程序员( junior_programmer ) 中级程序员 ( mid_programmer )高级程序员( adv_programmer)的工资
2 要求利用抽象类统一界面,方便程序的扩展, 比如:新增, 计算 架构师 (architect ) 的工资
*/
5面向抽象类编程思想强化
理论知识
- 虚函数和多态性使成员函数根据调用对象的类型产生不同的动作
- 多态性特别适合于实现分层结构的软件系统,便于对问题抽象时 定义共性,实现时定义区别
- 面向抽象类编程(面向接口编程)是项目开发中重要技能之一。
4.1案例:socket库c++模型设计和实现
企业信息系统框架集成第三方产品
案例背景:一般的企业信息系统都有成熟的框架。软件框架一般不发生变化,能自由的集成第三方厂商的产品。
案例需求:请你在企业信息系统框架中集成第三方厂商的Socket通信产品和第三方厂商加密产品。
第三方厂商的Socket通信产品:完成两点之间的通信;
第三方厂商加密产品:完成数据发送时加密;数据解密时解密。
案例要求: 1)能支持多个厂商的Socket通信产品入围
2)能支持多个第三方厂商加密产品的入围
3)企业信息系统框架不轻易发生框架
需求实现
思考1:企业信息系统框架、第三方产品如何分层
思考2:企业信息系统框架,如何自由集成第三方产品(软件设计:模块要求松、接口要求紧)
思考3:软件分成以后,开发企业信息系统框架的程序员,应该做什么?
第三方产品入围应该做什么?
编码实现
分析有多少个类 CSocketProtocol CSckFactoryImp1 CSckFactoryImp2
CEncDesProtocol HwEncdes ciscoEncdes
- 定义 CSocketProtocol 抽象类
- 编写框架函数
- 编写框架测试函数
- 厂商1(CSckFactoryImp1)实现CSocketProtocol、厂商2(CSckFactoryImp1)实现CSocketProtoco
- 抽象加密接口(CEncDesProtocol)、加密厂商1(CHwImp)、加密厂商2(CCiscoImp)),集成实现业务模型
- 框架(c语言函数方式,框架函数;c++类方式,框架类)
几个重要的面向对象思想
继承-组合(强弱)
注入
控制反转 IOC
MVC :业务逻辑、数据、界面显示分离的方法
面向对象思想扩展aop(AOP是OOP的延续)思想
aop思想是对继承编程思想的有力的补充
4.2案例:计算员工工资
4.3案例:计算几何体的表面积和体积
6 C面向接口编程和C多态
结论: 只要你动手,又很容易!
6.1函数类型语法基础
函数三要素: 名称、参数、返回值 C语言中的函数有自己特定的类型 |
C语言中通过typedef为函数类型重命名 typedef type name(parameter list) typedef int f(int, int); typedef void p(int); |
函数指针 |
函数指针用于指向一个函数 函数名是函数体的入口地址 1)可通过函数类型定义函数指针: FuncType* pointer; 2)也可以直接定义:type (*pointer)(parameter list); pointer为函数指针变量名 type为指向函数的返回值类型 parameter list为指向函数的参数类型列表 |
函数指针语法梳理 //函数类型 //函数指针类型 //函数指针变量
数组指针语法梳理 //数组类型语法 //数组指针类型 //数组指针变量 |
typedef
int test(int { return }
void f() { printf("Call f()...\n"); }
int main() { FUNC* pt = test;
void(*pf)() = &f;
pf(); (*pf)();
printf("Function pointer call: %d\n", pt(3)); } |
6.2函数指针做函数参数
一级指针做函数参数、二级。。。。、三级 |
当函数指针 做为函数的参数,传递给一个被调用函数, 被调用函数就可以通过这个指针调用外部的函数,这就形成了回调 |
3、练习 int add(int a, int b); int libfun(int(*pDis)(int a, int b));
int main(void) { int(*pfun)(int a, int b); pfun = add; libfun(pfun);
}
int add(int { return
}
int libfun(int(*pDis)(int a, int b)) { int a, b; a = 1; b = 2; add(1, 3) //直接调用add函数 printf("%d", pDis(a, b)); //通过函数指针做函数参数,间接调用add函数 //思考 这样写 pDis(a, b)有什么好处? } //剖析思路 //1函数的调用 和 函数的实现 有效的分离 //2 C++的多态,可扩展
现在这几个函数是在同一个文件当中 假如 int libfun(int(*pDis)(int a, int b)) 是一个库中的函数,就只有使用回调了,通过函数指针参数将外部函数地址传入 来实现调用
函数 add 的代码作了修改,也不必改动库的代码,就可以正常实现调用 便于程序的维护和升级 |
回调函数思想:
结论:回调函数的本质:提前做了一个协议的约定(把函数的参数、函数返回值提前约定)
请思考:C编译器通过那个具体的语法,实现解耦合的?
C++编译器通过多态的机制(提前布局vptr指针和虚函数表,找虚函数入口地址来实现)
6.3函数指针正向调用
|
2、函数指针做函数参数 被调用函数和主调函数不在同一个文件中、模块中。 难点:理解被调用函数是什么机制被调用起来的。框架 框架提前设置了被调用函数的入口(框架提供了第三方模块入口地址的集成功能) 框架具备调用第三方模块入口函数 |
1、 练习
typedef
int MyEncDataFunc(unsigned { int rv = 0; char *p = "222222222222";
strcpy(outData, p); *outDataLen = strlen(p); return rv; }
int Send_Data(EncDataFunc encDataFunc, unsigned { int rv = 0; if (encDataFunc != NULL) { rv = encDataFunc(inData, inDataLen, outData, outDatalen, NULL, 0); if (rv != 0) { printf("func encDataFunc() err.\n"); return rv; } } return rv; }
int main() { int rv = 0;
EncDataFunc encDataFunc = NULL; encDataFunc = MyEncDataFunc;
// 第一个调用 { unsigned int inDataLen; unsigned int outDatalen; strcpy(inData, "1111"); inDataLen = strlen(inData); rv = encDataFunc(inData, inDataLen, outData, &outDatalen, NULL, 0); if (rv != 0) { printf("edf err .....\n"); } else { printf("edf ok \n"); printf("%s \n", outData); } }
{ unsigned int inDataLen; unsigned int outDatalen; strcpy(inData, "3333"); inDataLen = strlen(inData); rv = Send_Data(MyEncDataFunc, inData, inDataLen, outData, &outDatalen); if (rv != 0) { printf("func Send_Data err:%d", rv); return rv; } printf("%s \n", outData); }
getchar(); } |
6.4函数指针反向调用
回调函数效果展示。
6.C动态库升级成框架案例
C语言版本Socket动态库升级成框架集成第三方产品
简称:C动态库升级成框架案例
名字解释
动态库:抽象类一个套接口,单独封装成模块,供别人调用;无法扩展。
框架:能自由的扩展
案例背景:一般的企业信息系统都有成熟的框架,可以有C语言写,也可以由C++语言。软件框架一般不发生变化,能自由的集成第三方厂商的产品。
案例需求:在socket通信库中,完成数据加密功能,有n个厂商的加密产品供你选择,如何实现动态库和第三个厂商产品的解耦合。
提醒:C++通过抽象类,也就是面向抽象类编程实现的(相当于C++编译器通过多态机制,已经很好用了。提前布局vptr指针、虚函数表;调用是迟绑定完成。),
C语言中如何实现哪?
案例要求: 1)能支持多个第三方厂商加密产品的入围
2)企业信息系统框架不轻易发生框架
需求实现思路分析
思考1:企业信息系统框架、第三方产品如何分层
思考2:企业信息系统框架,如何自由集成第三方产品
(软件设计:模块要求松、接口要求紧)
思考3:软件分层确定后,动态库应该做什么?产品入围厂商应该做什么?
以后,开发企业信息系统框架的程序员,应该做什么?
第三方产品入围应该做什么?
编码实现
- 动态库中定义协议,并完成任务的调用
typedef int (*EncData)(unsigned char *inData,int inDataLen,unsigned char *outData,int *outDataLen,void *Ref, int RefLen);
typedef int (*DecData)(unsigned char *inData,int inDataLen,unsigned char *outData,int *outDataLen,void *Ref, int RefLen);
- 加密厂商完成协议函数的编写
- 对接调试。
- 动态库中可以缓存第三方函数的入口地址,也可以不缓存,两种实现方式。
案例总结
回调函数:利用函数指针做函数参数,实现的一种调用机制,具体任务的实现者,可以不知道什么时候被调用。
回调机制原理:
当具体事件发生时,调用者通过函数指针调用具体函数
回调机制的将调用者和被调函数分开,两者互不依赖
任务的实现 和 任务的调用 可以耦合 (提前进行接口的封装和设计)
6.6附录:诸葛亮的锦囊妙计
刘备利用周瑜、曹仁厮杀之际,乘虚袭取了南郡、荆州、襄阳,以后又征服了长沙等四郡。周瑜想想十分气恨,正无处报复以夺还荆州。不久,刘备忽然丧偶,周瑜计上心来,对孙权说:"您的妹妹,美丽、刚强,我们以联姻抗曹名义向刘备招亲,把他骗来南徐幽禁,逼他们拿荆州来换。"孙权大喜,郎派人到荆州说亲。
刘备认为这是骗局,想要拒绝,诸葛亮笑道:"送个好妻子上门何不答应?您只管去东吴,我叫赵云陪您去,自有安排,包您得了夫人又不失荆州。"
接着,诸葛亮暗暗关照赵云道:"我这里有三个锦囊,内藏三条妙计。到南徐时打开第一个,到年底时打开第二个,危急无路时打开第三个。"
第一个锦囊
一到东吴就拜会乔国老
第二个锦囊
刘备被孙权设计留下就对他谎称曹操大军压境
第三个锦囊
被东吴军队追赶就求孙夫人解围
C++复习:纯虚函数和抽象类的更多相关文章
- C++基础 (7) 第七天 多态的原理 纯虚函数和抽象类 依赖倒置原则
1 昨日回顾 2 多态的原理 1 要有继承 2 要有子类重写父类的虚函数 3 父类指针(或者引用)指向子类对象 (动态联编 虚函数表 3 证明vptr指针的存在 4 vptr指针在构造父类的时候是分步 ...
- C++学习基础十二——纯虚函数与抽象类
一.C++中纯虚函数与抽象类: 1.含有一个或多个纯虚函数的类成为抽象类,注意此处是纯虚函数,而不是虚函数. 2.如果一个子类继承抽象类,则必须实现父类中的纯虚函数,否则该类也为抽象类. 3.如果一个 ...
- C++基础(纯虚函数与抽象类)
C++基础之纯虚函数与抽象类 引言 纯虚函数在C++编程中的地位很重要,其关联到了设计模式中"接口"的概念. 语法 纯虚函数的语法: 1. 将成员函数声明为virtual 2. ...
- C++:纯虚函数与抽象类
5.4.3 纯虚函数和抽象类 纯虚函数是一个在基类中说明的虚函数,它在该基类中没有定义,但是要求在派生类中根据需要对它进行定义,或仍然说明为纯虚函数. 声明纯虚函数的一般格式是: virtual 函数 ...
- c++,纯虚函数与抽象类
1.纯虚函数的定义: (1)虚函数被“初始化”为0的函数.声明纯虚函数的一般形式是virtual 函数类型 函数名(参数表列) =0;(2)纯虚函数没有函数体:(3)最后面的“=0”并不表示函数返回值 ...
- 简单地说, cpp中的纯虚函数就是抽象类的具体实现
简单地说, cpp中的纯虚函数就是抽象类的具体实现.包含了纯虚函数的类就是抽象类.
- c++-纯虚函数和抽象类
纯虚函数和抽象类 C面向接口编程和C多态 函数类型语法基础 函数指针做函数参数(回调函数)思想剖析 函数指针做函数参数两种用法(正向调用.反向调用) 纯虚函数 抽象类 抽象类基本概念 抽象类在多继承中 ...
- C++开发系列-纯虚函数和抽象类
概念 纯虚函数和抽象类 纯虚函数是一个在基类中说明的虚函数,在基类中没有定义,要求任何派生类都实现该函数. 纯虚函数为各派生类提供了一个公共界面(接口的封装和设计.软件的模块功能的划分) 纯虚函数说明 ...
- cc32b_demo-32dk2j_cpp_纯虚函数与抽象类2-txwtech
cc32b_demo-32dk2j_cpp_纯虚函数与抽象类2-txwtech //纯虚函数是用来继承用的//纯虚函数//抽象类-抽象数据类型//*任何包含一个或者多个纯虚函数的类都是抽象类//*不要 ...
随机推荐
- 事件之onTouch方法的执行过程 及和 onClick执行发生冲突的解决办法
转载:http://blog.csdn.net/jiangwei0910410003/article/details/17504315#quote 博主推荐: 风萧兮兮易水寒,“天真”一去兮不复还.如 ...
- [UE4]Task的定义与使用
在Task蓝图里面可以像普通蓝图一样添加函数.变量. 也可以通过使用“set blackboard value as”设置黑板变量,使用“get blackboard value as”获得黑板变量值 ...
- utf8_unicode_ci、utf8_general_ci区别
摘录一下Mysql 5.1中文手册中关于utf8_unicode_ci与utf8_general_ci的说明: 当前,utf8_unicode_ci校对规则仅部分支持Unicode校对规则算法.一 ...
- mysql连接状态
mysql连接状态 mysqladmin -uroot -h127.0.0.1 status mysqladmin -uroot -h127.0.0.1 processlist
- ZooKeeper系列(10):ZooKeeper与Dubbo的结合
1. Dubbo的快速讲解 以防有人对Dubbo不了解,快速过一下Dubbo的基本概念,下面简单引用一下官方的介绍 1.1 架构 1.2.角色说明 Provider:暴露服务的提供方 Consumer ...
- VS远程调试与附加调试
使用场景 假如你要开发的程序需要运行在独特的硬件上,比如:服务器,然而这个"独特的硬件"却不能给你装VS,这时候远程调试就登场了. 测试工具/环境一览 Key Value VS版本 ...
- 使用Excel随机函数产生大众评委的6位登录密码
第一步:填写公式 如下图所示:选中B2单元格输入公式 =TEXT(ROUNDUP(RAND()*1000000,0),"000000") ,然后回车. 可复制的纯文本格式: = ...
- Qt Xml Dom
//Dom方式更改节点信息 bool XmlTools::SetValue(QString name,float exposure,float gain,float gamma,int brightn ...
- 使用Mongo dump 将数据导入到hive
概述:使用dump 方式将mongo数据导出,上传到hdfs,然后在hive中建立外部表. 1. 使用mongodump 将集合导出 mongodump --host=localhost:27 ...
- 30 个 OpenStack 经典面试问题和解答
现在,大多数公司都试图将它们的 IT 基础设施和电信设施迁移到私有云, 如 OpenStack.如果你打算面试 OpenStack 管理员这个岗位,那么下面列出的这些面试问题可能会帮助你通过面试.-- ...