Day15(下).工程开发中的抽象类
2015-07-03 14:44
344 查看
纯虚函数
纯虚函数是一个在基类中说明的虚函数,在基类中没有定义,要求任何派生类都定义自己的版本
纯虚函数为各派生类提供一个公共界面
纯虚函数形式:
vortual 类型 函数名(参数表) = 0;
shape x; //error 抽象类不能建立对象
shape *p; //ok 可以声明抽象类的指针
shape f(); //error 抽象类不能作为返回类型
void g(shape); //error 抽象类不能作为参数类型
shape &h(shape &) //ok 可以声明抽象类的引用
看代码:
小结:
1. 如果子类继承抽象类,只有把所有的纯虚函数都实现了,才能实例化
2. 抽象类可以定义普通的函数 变量。。
多继承
在实际开发经验中,多继承已经被抛弃,几乎不被使用
多继承带来的代码复杂性远多于带来的便利性
多继承对代码维护性上的影响是灾难性的
在设计方法上,任何多继承都可以用单继承代替
代码:
C++中没有接口的概念,C++中可以使用纯虚函数实现接口,接口类中只有函数原型定义,没有任何数据的定义。
C++中接口的封装、设计和模块界面分工(软件架构初步)
纯虚函数为各派生类提供一个公共界面(实际上就是接口的封装和设计)
剩下的代码是以socket通信为例的,代码如下:
纯虚函数是一个在基类中说明的虚函数,在基类中没有定义,要求任何派生类都定义自己的版本
纯虚函数为各派生类提供一个公共界面
纯虚函数形式:
vortual 类型 函数名(参数表) = 0;
class point {/*.................*/ }; class shape //抽象类 { point center; /*.................*/ public: point where() { return center; } void move(point p) { enter = p; draw(); } virtual void rotate(int) = 0; virtual void draw() = 0; };
shape x; //error 抽象类不能建立对象
shape *p; //ok 可以声明抽象类的指针
shape f(); //error 抽象类不能作为返回类型
void g(shape); //error 抽象类不能作为参数类型
shape &h(shape &) //ok 可以声明抽象类的引用
看代码:
#include "iostream" using namespace std; //定义一个抽象类,含有纯虚函数的类叫抽象类 class figure { public: <strong><span style="color:#FF0000;">virtual void show_area() = 0;</span></strong> protected: double x; double y; }; class trigle :public figure { public: <span style="color:#FF0000;"><strong>void show_area()</strong></span> { cout << "三角形面积" << endl; } }; class square :public figure { <span style="color:#FF0000;"><strong>void show_area()</strong></span> { cout << "四边形面积" << endl; } }; class circle :public figure { <span style="color:#FF0000;"><strong>void show_area()</strong></span> { cout << "圆的面积" << endl; } }; //通过抽象类的纯虚函数接口约定(公共界面的约定)来实现具体的业务模型的填充 //(比继承代码复用更好的一个级别,属于框架的设计) void objshow(figure *pBase) { pBase->show_area(); } void main() { //抽象类不能定义对象 //figure f1; //抽象类可以定义指针 figure *pBase = NULL; trigle t1; square s1; circle c1; objshow(&t1); objshow(&s1); objshow(&c1); system("pause"); }
小结:
1. 如果子类继承抽象类,只有把所有的纯虚函数都实现了,才能实例化
2. 抽象类可以定义普通的函数 变量。。
多继承
在实际开发经验中,多继承已经被抛弃,几乎不被使用
多继承带来的代码复杂性远多于带来的便利性
多继承对代码维护性上的影响是灾难性的
在设计方法上,任何多继承都可以用单继承代替
代码:
#include "iostream" using namespace std; class parent { public: int i; }; class interface1 { public: virtual void print() = 0; virtual int add(int i, int j) = 0; }; class interface2 { public: virtual int add(int i, int j) = 0; virtual int minus(int i, int j) = 0; }; //多继承几乎都是这么用的,后两个是协议或接口 class child :public parent, public interface1, public interface2 { public: void print() { cout << "child print()" << endl; } int add(int i, int j) { return i + j; } int minus(int i, int j) { return i - j; } }; void 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"); }注意的是:
C++中没有接口的概念,C++中可以使用纯虚函数实现接口,接口类中只有函数原型定义,没有任何数据的定义。
C++中接口的封装、设计和模块界面分工(软件架构初步)
纯虚函数为各派生类提供一个公共界面(实际上就是接口的封装和设计)
剩下的代码是以socket通信为例的,代码如下:
//SocketProtocol.h #pragma once class SocketIF { public: //客户端初始化 获取handle 上下文信息 virtual int cltSocketInit() = 0; //客户端发报文 virtual int cltSocketSend( unsigned char *buf , int buflen ) = 0; //客户端收报文 virtual int cltSocketRev( unsigned char *buf , int *buflen ) = 0; //客户端释放资源 virtual int cltSocketDestory() = 0; };
//SocketImp.h #pragma once #include "socketprotocol.h" class SocketImp1 :public SocketIF { public: SocketImp1(void); ~SocketImp1(void); public: int cltSocketInit(); //客户端发报文 int cltSocketSend( unsigned char *buf , int buflen ); //客户端收报文 int cltSocketRev( unsigned char *buf , int *buflen ); //客户端释放资源 int cltSocketDestory(); private: char *pcommon; int len; };
//SocketImp1.cpp #include <stdio.h> #include <stdlib.h> #include <string.h> #include "SocketImp1.h" SocketImp1::SocketImp1(void) { } SocketImp1::~SocketImp1(void) { } int SocketImp1::cltSocketInit() { return 0; } //客户端发报文 int SocketImp1::cltSocketSend( unsigned char *buf , int buflen ) { pcommon = (char *)malloc((buflen+1)*sizeof(char)); //pcommon[len-1] = 0; len = buflen; memcpy(pcommon,buf,buflen); return 0; } //客户端收报文 int SocketImp1::cltSocketRev( unsigned char *buf , int *buflen ) { memcpy(buf,pcommon,len); *buflen = len; return 0; } //客户端释放资源 int SocketImp1::cltSocketDestory() { if (pcommon != NULL) { delete[] pcommon; } return 0; }
//mainclass.cpp #include "iostream" #include "SocketImp1.h" #include "SocketProtocol.h" using namespace std; //Ö÷¿ò¼Ü void mainOP01() { SocketIF *sIf = new SocketImp1(); unsigned char buf[1024]; strcpy((char *)buf, "ddddddddddddddsssssssssssssssssssss"); int buflen = 10; unsigned char out[1024]; int outlen = 10; sIf->cltSocketInit(); sIf->cltSocketSend(buf, buflen); sIf->cltSocketRev(out, &outlen); sIf->cltSocketDestory(); } int mainOP02(SocketIF *sIf, unsigned char *in, int inlen, unsigned char *out, int *outlen) { int ret = 0; ret = sIf->cltSocketInit(); ret = sIf->cltSocketSend(in, inlen); ret = sIf->cltSocketRev(out, outlen); ret = sIf->cltSocketDestory(); return ret; } void main() { SocketIF *sIf = new SocketImp1(); unsigned char buf[1024]; strcpy((char *)buf, "ddddddddddddddsssssssssssssssssssss"); int buflen = 10; unsigned char out[1024]; int outlen = 10; mainOP02(sIf, buf, buflen, out, &outlen); cout<<out<<endl; system("pause"); }以防万一,这里给出整个工程的压缩包下载地址:http://pan.baidu.com/s/1eQCSmQ2
相关文章推荐
- BitTorrent协议规范
- 米尔科技强势推出多功能Xilinx Zynq-7010/7020开发平台-MYD-C7Z010/20开发板
- java 匿名内部类
- 如何理解int *(*a[5])(int, char*);
- Android Exception 17(database or disk is full)
- CCID: 2014-2015年度中国信息安全产品市场研究年度报告
- C#冒泡法排序算法实例分析
- SD卡文件系统
- Mybatis Generator配置文件
- Linux系统调用--getitimer/setitimer函数详解
- android屏幕framebuffer绘图
- pub.php文件方法示意图
- DataTable操作
- 各种正则匹配总结
- 想做一个关于IT项目管理的调查问卷
- meta 中name="viewport" 的含义
- meta 中name="viewport" 的含义
- objective-c 中new与alloc/init的区别
- Spring Web Flow 入门demo(三)嵌套流程与业务结合 附源码
- 金融经济