福建网站开发公司电话,成都丁香人才网官网专区,网站建设教育类旧式网站,徐州制作网站的公司有哪些纯虚函数和抽象类
1.基本概念 2.案例
#include iostream
using namespace std;////面向抽象类编程(面向一套预先定义好的接口编程)//解耦合 ....模块的划分class Figure //抽象类
{
public://阅读一个统一的界面(接口),让子类使用,让子类必须去实现virtual void get…纯虚函数和抽象类
1.基本概念 2.案例
#include iostream
using namespace std;////面向抽象类编程(面向一套预先定义好的接口编程)//解耦合 ....模块的划分class Figure //抽象类
{
public://阅读一个统一的界面(接口),让子类使用,让子类必须去实现virtual void getArea() 0 ; //纯虚函数
protected:
private:
};class Circle : public Figure
{
public:Circle(int a, int b){this-a a;this-b b;}virtual void getArea(){cout圆形的面积: 3.14*a*aendl;;}private:int a;int b;
};class Tri : public Figure
{
public:Tri(int a, int b){this-a a;this-b b;}virtual void getArea() {cout三角形的面积: a*b/2endl;;}private:int a;int b;
};class Square : public Figure
{
public:Square(int a, int b){this-a a;this-b b;}virtual void getArea() {cout四边形的面积: a*bendl;;}private:int a;int b;
};void objplay(Figure *base)
{base-getArea(); //会发生多态
}void main511()
{//Figure f; //抽象类不能被实例化Figure *base NULL; //抽象类不能被实例化Circle c1(10, 20);Tri t1(20, 30);Square s1(50, 60);//面向抽象类编程(面向一套预先定义好的接口编程)objplay(c1);objplay(t1);objplay(s1);//c1.getArea();couthello...endl;system(pause);return ;
}
3.抽象类在多继承中的应用
C中没有Java中的接口概念抽象类可以模拟Java中的接口类。接口和协议
工程上的多继承 被实际开发经验抛弃的多继承工程开发中真正意义上的多继承是几乎不被使用的多重继承带来的代码复杂性远多于其带来的便利多重继承对代码维护性上的影响是灾难性的在设计方法上任何多继承都可以用单继承代替多继承中的二义性和多继承不能解决的问题 C没有接口只有多继承和抽象类 绝大多数面向对象语言都不支持多继承绝大多数面向对象语言都支持接口的概念C中没有接口的概念C中可以使用纯虚函数实现接口接口类中只有函数原型定(纯虚函数)义没有任何数据的定义。
class Interface
{public:virtual void func1() 0;virtual void func2(int i) 0;virtual void func3(int i) 0;
};
实际工程经验证明 多重继承接口不会带来二义性和复杂性等问题多重继承可以通过精心设计用单继承和接口来代替接口类只是一个功能说明而不是功能实现。子类需要根据功能说明定义功能实现。多继承的二义性
#include iostream
using namespace std;class B
{
public:int b;
protected:
private:
};class B1 : virtual public B
{
public:int b1;
protected:
private:
};class B2 : virtual public B
{
public:int b2;
protected:
private:
};class C : public B1, public B2
{
public:int c;
protected:
private:
};void main61()
{C myc;myc.c 10;myc.b 100;//二义性 error C2385: 对“b”的访问不明确couthello...endl;system(pause);return ;
}
抽象类和多继承更配哦
#include iostream
using namespace std;class Interface1
{
public:virtual int add(int a, int b) 0;virtual void print() 0;
};class Interface2
{
public:virtual int mult(int a, int b) 0;virtual void print() 0;
};class Parent
{
public:int getA(){a 0;return a;}
protected:
private:int a;
};class Child : public Parent, public Interface1, public Interface2
{
public:virtual int add(int a, int b){coutChild: add()已经执行\n;return a b;}virtual void print(){coutChild: print()已经执行\n;}virtual int mult(int a, int b){coutChild: mult()已经执行\n;return a*b;}
protected:
private:
};void main71()
{Child c1;c1.print();Interface1 *it1 c1;it1-add(1, 2);Interface2 *it2 c1;it2-mult(3, 6);couthello...endl;system(pause);return ;
}
4.面向抽象类编程
计算程序猿工资
#include iostream
using namespace std;class programer{
public:virtual int getSal() 0;
};class junior_programer :public programer
{
private:char *name;char *obj;int sal;
public:junior_programer(char *_name,char *_obj,int _sal){name _name;obj _obj;sal _sal;}virtual int getSal(){cout name obj : sal endl;return sal;}
protected:
};class mid_programer :public programer
{
private:char *name;char *obj;int sal;
public:mid_programer(char *_name, char *_obj, int _sal){name _name;obj _obj;sal _sal;}virtual int getSal(){cout name obj : sal endl;return sal;}
protected:
};class adv_programer :public programer
{
private:char *name;char *obj;int sal;
public:adv_programer(char *_name, char *_obj, int _sal){name _name;obj _obj;sal _sal;}virtual int getSal(){cout name obj : sal endl;return sal;}
protected:
};class arch_programer :public programer
{
private:char *name;char *obj;int sal;
public:arch_programer(char *_name, char *_obj, int _sal){name _name;obj _obj;sal _sal;}virtual int getSal(){cout name obj : sal endl;return sal;}
protected:
};void CalProgSal(programer *base)
{base-getSal();
}int main(void)
{junior_programer jp(小王, 初级, 4000);mid_programer mp(小张, 中级, 8600);adv_programer ap(小李, 高级, 15000);//系统扩展arch_programer ar(高水平学员, 架构师, 24000);CalProgSal(jp);CalProgSal(mp);CalProgSal(ap);CalProgSal(ar);coutHello!endl;system(pause);return 0;
}
5.socket库c模型设计和实现
企业信息系统框架集成第三方产品
案例背景一般的企业信息系统都有成熟的框架。软件框架一般不发生变化能自由的集成第三方厂商的产品。案例需求请你在企业信息系统框架中集成第三方厂商的Socket通信产品和第三方厂商加密产品。 第三方厂商的Socket通信产品完成两点之间的通信第三方厂商加密产品完成数据发送时加密数据解密时解密。 案例要求 1能支持多个厂商的Socket通信产品入围 2能支持多个第三方厂商加密产品的入围 3企业信息系统框架不轻易发生框架 需求实现
思考1企业信息系统框架、第三方产品如何分层思考2企业信息系统框架如何自由集成第三方产品 软件设计模块要求松、接口要求紧思考3软件分成以后开发企业信息系统框架的程序员应该做什么第三方产品入围应该做什么 编码实现 分析有多少个类 CSocketProtocol CSckFactoryImp1 CSckFactoryImp2 CEncDesProtocol HwEncdes ciscoEncdes 1、 定义 CSocketProtocol 抽象类 2、 编写框架函数 3、 编写框架测试函数 4、 厂商1CSckFactoryImp1实现CSocketProtocol、厂商2CSckFactoryImp1实现CSocketProtoco 5、 抽象加密接口CEncDesProtocol、加密厂商1(CHwImp)、加密厂商2(CCiscoImp))集成实现业务模型 6、 框架c语言函数方式框架函数c类方式框架类
几个重要的面向对象思想 * 继承-组合强弱 * 注入 * 控制反转 IOC * MVC * 面向对象思想扩展aop思想:aop思想是对继承编程思想的有力的补充
实现步骤
定义socket的抽象类和纯虚函数
#pragma once#include iostream
using namespace std;class CSocketProtocol
{
public:CSocketProtocol(){;}virtual ~CSocketProtocol() //虚析构函数的细节{;}//客户端初始化 获取handle上下virtual int cltSocketInit( /*out*/) 0; //客户端发报文virtual int cltSocketSend( unsigned char *buf /*in*/, int buflen /*in*/) 0; //客户端收报文virtual int cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/) 0;//客户端释放资源virtual int cltSocketDestory() 0;};
2.厂商一的功能实现
类的头文件
#pragma once#include iostream
using namespace std;
#include CSocketProtocol.hclass CSckFactoryImp1 : public CSocketProtocol
{
public://客户端初始化 获取handle上下virtual int cltSocketInit( /*out*/); //客户端发报文virtual int cltSocketSend( unsigned char *buf /*in*/, int buflen /*in*/); //客户端收报文virtual int cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/);//客户端释放资源virtual int cltSocketDestory();private:unsigned char *p;int len ;
};
类的实现文件
#include iostream
using namespace std;#include CSckFactoryImp1.h//客户端初始化 获取handle上下int CSckFactoryImp1::cltSocketInit( /*out*/){p NULL;len 0 ;return 0;}//客户端发报文int CSckFactoryImp1::cltSocketSend( unsigned char *buf /*in*/, int buflen /*in*/){p (unsigned char * ) malloc(sizeof(unsigned char) * buflen);if (p NULL){return -1;}memcpy(p, buf, buflen);len buflen;return 0;}//客户端收报文int CSckFactoryImp1::cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/){if (bufNULL || buflenNULL){return -1;}*buflen this-len ;memcpy(buf, this-p, this-len);return 0;}//客户端释放资源int CSckFactoryImp1::cltSocketDestory(){if (p ! NULL){free(p);p NULL;len 0;}return 0;}
3.厂商二的功能实现
类的头文件
#pragma once#include iostream
using namespace std;
#include CSocketProtocol.hclass CSckFactoryImp2 : public CSocketProtocol
{
public://客户端初始化 获取handle上下virtual int cltSocketInit( /*out*/); //客户端发报文virtual int cltSocketSend( unsigned char *buf /*in*/, int buflen /*in*/); //客户端收报文virtual int cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/);//客户端释放资源virtual int cltSocketDestory();private:unsigned char *p;int len ;
};
类的实现文件
#include iostream
using namespace std;#include CSckFactoryImp2.h//客户端初始化 获取handle上下
int CSckFactoryImp2::cltSocketInit( /*out*/)
{p NULL;len 0 ;return 0;
}//客户端发报文
int CSckFactoryImp2::cltSocketSend( unsigned char *buf /*in*/, int buflen /*in*/)
{p (unsigned char * ) malloc(sizeof(unsigned char) * buflen);if (p NULL){return -1;}memcpy(p, buf, buflen);len buflen;return 0;
}//客户端收报文
int CSckFactoryImp2::cltSocketRev( unsigned char *buf /*in*/, int *buflen /*in out*/)
{if (bufNULL || buflenNULL){return -1;}*buflen this-len ;memcpy(buf, this-p, this-len);return 0;
}//客户端释放资源
int CSckFactoryImp2::cltSocketDestory()
{if (p ! NULL){free(p);p NULL;len 0;}return 0;
}
4.测试socket功能文件
#define _CRT_SECURE_NO_WARNINGS
#include iostream
using namespace std;#include CSocketProtocol.h
#include CSckFactoryImp1.h
#include CSckFactoryImp2.h//面向抽象类编程,框架实现完毕
int SckSendAndRec01(CSocketProtocol *sp, unsigned char *in, int inlen, unsigned char *out, int *outlen)
{int ret 0;ret sp-cltSocketInit();if (ret ! 0){goto End;}ret sp-cltSocketSend(in, inlen);if (ret ! 0){goto End;}ret sp-cltSocketRev(out, outlen);if (ret ! 0){goto End;}End:ret sp-cltSocketDestory();return 0;
}//写一个框架
int main011()
{int ret 0;unsigned char in[4096];int inlen;unsigned char out[4096];int outlen 0;strcpy((char *)in, aadddddddddddaaaaaaaaaaa);inlen 9;CSocketProtocol *sp NULL;//sp new CSckFactoryImp1sp new CSckFactoryImp2; //ret SckSendAndRec01(sp, in, inlen, out, outlen);if (ret ! 0){printf(func SckSendAndRec() err:%d \n, ret);return ret;}delete sp; //想通过父类指针 释放所有的子类对象的资源 ..couthello...endl;system(pause);return ret;
}
5.加密协议抽象类的定义
#pragma onceclass CEncDesProtocol
{
public:CEncDesProtocol(){}virtual ~CEncDesProtocol(){}virtual int EncData(unsigned char *plain, int plainlen, unsigned char *cryptdata, int *cryptlen) 0;virtual int DecData(unsigned char *cryptdata, int cryptlen, unsigned char *plain, int *plainlen) 0;};
6.厂商一的加密功能实现
类的头文件
#include iostream
using namespace std;#include CEncDesProtocol.hclass HwEncDec : public CEncDesProtocol
{
public:virtual int EncData(unsigned char *plain, int plainlen, unsigned char *cryptdata, int *cryptlen);virtual int DecData(unsigned char *cryptdata, int cryptlen, unsigned char *plain, int *plainlen);
};类的实现文件
#include iostream
using namespace std;
#include HwEncDec.h
#include des.hint HwEncDec::EncData(unsigned char *plain, int plainlen, unsigned char *cryptdata, int *cryptlen)
{int ret 0;//用户使用的函数ret DesEnc(plain,plainlen, cryptdata, cryptlen);if (ret ! 0){printf(func DesEnc() err:%d \n , ret);return ret;}return ret;
}int HwEncDec::DecData(unsigned char *cryptdata, int cryptlen, unsigned char *plain, int *plainlen)
{int ret 0;//用户使用函数des解密ret DesDec(cryptdata, cryptlen, plain, plainlen);if (ret ! 0){printf(func DesDec() err:%d \n , ret);return ret;}return ret;
}
7.加密功能的测试文件
#define _CRT_SECURE_NO_WARNINGS
#include iostream
using namespace std;#include CSocketProtocol.h
#include CSckFactoryImp1.h
#include CSckFactoryImp2.h#include CEncDesProtocol.h
#include HwEncDec.h//面向抽象类编程,框架实现完毕
int SckSendAndRec(CSocketProtocol *sp, unsigned char *in, int inlen, unsigned char *out, int *outlen)
{int ret 0;ret sp-cltSocketInit();if (ret ! 0){goto End;}ret sp-cltSocketSend(in, inlen);if (ret ! 0){goto End;}ret sp-cltSocketRev(out, outlen);if (ret ! 0){goto End;}End:ret sp-cltSocketDestory();return 0;
}//面向抽象类编程,框架实现完毕
//c函数
int SckSendAndRec_EncDec(CSocketProtocol *sp, CEncDesProtocol *ed, unsigned char *in, int inlen, unsigned char *out, int *outlen)
{int ret 0;unsigned char data[4096];int datalen 0;ret sp-cltSocketInit();if (ret ! 0){goto End;}ret ed-EncData(in,inlen, data, datalen);if (ret ! 0){goto End;}ret sp-cltSocketSend(data, datalen); //发送数据之前对数据加密 ..if (ret ! 0){goto End;}ret sp-cltSocketRev(data, datalen); //收到的数据是密文,需要进行解密if (ret ! 0){goto End;}ret ed-DecData(data, datalen, out, outlen );if (ret ! 0){goto End;}End:ret sp-cltSocketDestory();return 0;
}//写一个框架
int main022()
{int ret 0;unsigned char in[4096];int inlen;unsigned char out[4096];int outlen 0;strcpy((char *)in, aadddddddddddaaaaaaaaaaa);inlen 9;CSocketProtocol *sp NULL;CEncDesProtocol *ed NULL;//sp new CSckFactoryImp1sp new CSckFactoryImp2; //ed new HwEncDec;ret SckSendAndRec_EncDec(sp, ed, in, inlen, out, outlen);if (ret ! 0){printf(func SckSendAndRec() err:%d \n, ret);return ret;}delete sp; //想通过父类指针 释放所有的子类对象的资源 ..couthello...endl;system(pause);return ret;
} 加解密的代码是des.h和des.c可在前面“08文件操作”查看源代码。 8.将测试框架从函数形式升级为类的形式
#define _CRT_SECURE_NO_WARNINGS
#include iostream
using namespace std;#include CSocketProtocol.h
#include CSckFactoryImp1.h
#include CSckFactoryImp2.h#include CEncDesProtocol.h
#include HwEncDec.h//抽象类在多继承中的应用
/*
class MainOp : public CSocketProtocol, public CEncDesProtocol
{
public:
protected:
private:};
*/class MainOp
{
public:MainOp(){this-sp NULL;this-ed NULL;}MainOp(CSocketProtocol *sp, CEncDesProtocol *ed){this-sp sp;this-ed ed;}//void setSp(CSocketProtocol *sp){this-sp sp;}void setEd(CEncDesProtocol *ed){this-ed ed;}public://面向抽象类编程,框架实现完毕int SckSendAndRec_EncDec3(CSocketProtocol *sp, CEncDesProtocol *ed, unsigned char *in, int inlen, unsigned char *out, int *outlen){int ret 0;unsigned char data[4096];int datalen 0;ret sp-cltSocketInit();if (ret ! 0){goto End;}ret ed-EncData(in,inlen, data, datalen);if (ret ! 0){goto End;}ret sp-cltSocketSend(data, datalen); //发送数据之前对数据加密 ..if (ret ! 0){goto End;}ret sp-cltSocketRev(data, datalen); //收到的数据是密文,需要进行解密if (ret ! 0){goto End;}ret ed-DecData(data, datalen, out, outlen );if (ret ! 0){goto End;}End:ret sp-cltSocketDestory();return 0;}int SckSendAndRec_EncDec3(unsigned char *in, int inlen, unsigned char *out, int *outlen){int ret 0;unsigned char data[4096];int datalen 0;ret this-sp-cltSocketInit();if (ret ! 0){goto End;}ret this-ed-EncData(in,inlen, data, datalen);if (ret ! 0){goto End;}ret this-sp-cltSocketSend(data, datalen); //发送数据之前对数据加密 ..if (ret ! 0){goto End;}ret sp-cltSocketRev(data, datalen); //收到的数据是密文,需要进行解密if (ret ! 0){goto End;}ret ed-DecData(data, datalen, out, outlen );if (ret ! 0){goto End;}End:ret sp-cltSocketDestory();return 0;}private:CSocketProtocol *sp;CEncDesProtocol *ed;};//写一个框架
int main()
{int ret 0;unsigned char in[4096];int inlen;unsigned char out[4096];int outlen 0;strcpy((char *)in, aadddddddddddaaaaaaaaaaa);inlen 9;MainOp *myMainOp new MainOp;CSocketProtocol *sp NULL;CEncDesProtocol *ed NULL;//sp new CSckFactoryImp1sp new CSckFactoryImp2; //ed new HwEncDec;myMainOp-setSp(sp);myMainOp-setEd(ed);ret myMainOp-SckSendAndRec_EncDec3(in, inlen, out, outlen);if (ret! 0){printf(myMainOp SckSendAndRec_EncDec3() err\n , ret);}delete sp;delete ed;delete myMainOp;couthello...endl;system(pause);return ret;
} 无非就是将之前的全局函数封装在一个测试用的类里面然后该测试类拥有socket和加解密协议的基类对象作为该测试类的成员变量。 6.C语言回调函数和函数指针 结论回调函数的本质提前做了一个协议的约定把函数的参数、函数返回值提前约定 动态库升级为框架的编码实现 1、 动态库中定义协议并完成任务的调用
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);
2、 加密厂商完成协议函数的编写 3、 对接调试。 4、 动态库中可以缓存第三方函数的入口地址也可以不缓存两种实现方式。
案例总结
回调函数利用函数指针做函数参数实现的一种调用机制具体任务的实现者可以不知道什么时候被调用。回调机制原理 当具体事件发生时调用者通过函数指针调用具体函数回调机制将调用者和被调函数分开两者互不依赖任务的实现 和 任务的调用 可以耦合 提前进行接口的封装和设计