#include
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*a<
}
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<<"三角形的面积: "<2< }
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<<"四边形的面积: "< }
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();
cout<<"hello..."< system("pause");
return ;
}
C++中没有Java中的接口概念,抽象类可以模拟Java中的接口类。(接口和协议)
工程上的多继承
多继承中的二义性和多继承不能解决的问题
class Interface
{
public:
virtual void func1() = 0;
virtual void func2(int i) = 0;
virtual void func3(int i) = 0;
};
实际工程经验证明
多继承的二义性
#include
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”的访问不明确
cout<<"hello..."< system("pause");
return ;
}
#include
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)
{
cout<<"Child: add()已经执行\n";
return a + b;
}
virtual void print()
{
cout<<"Child: print()已经执行\n";
}
virtual int mult(int a, int b)
{
cout<<"Child: 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);
cout<<"hello..."< system("pause");
return ;
}
#include
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 <" " <": " < 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 <" " <": " < 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 <" " <": " < 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 <" " <": " < 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);
cout<<"Hello!"< system("pause");
return 0;
}
企业信息系统框架集成第三方产品
案例背景:一般的企业信息系统都有成熟的框架。软件框架一般不发生变化,能自由的集成第三方厂商的产品。
案例需求:请你在企业信息系统框架中集成第三方厂商的Socket通信产品和第三方厂商加密产品。
案例要求:
1)能支持多个厂商的Socket通信产品入围
2)能支持多个第三方厂商加密产品的入围
3)企业信息系统框架不轻易发生框架
需求实现
编码实现
分析有多少个类 CSocketProtocol CSckFactoryImp1 CSckFactoryImp2
CEncDesProtocol HwEncdes ciscoEncdes
1、 定义 CSocketProtocol 抽象类
2、 编写框架函数
3、 编写框架测试函数
4、 厂商1(CSckFactoryImp1)实现CSocketProtocol、厂商2(CSckFactoryImp1)实现CSocketProtoco
5、 抽象加密接口(CEncDesProtocol)、加密厂商1(CHwImp)、加密厂商2(CCiscoImp)),集成实现业务模型
6、 框架(c语言函数方式,框架函数;c++类方式,框架类)
几个重要的面向对象思想
* 继承-组合(强弱)
* 注入
* 控制反转 IOC
* MVC
* 面向对象思想扩展aop思想:aop思想是对继承编程思想的有力的补充
实现步骤
#pragma once
#include
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
using namespace std;
#include "CSocketProtocol.h"
class 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
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 (buf==NULL || buflen==NULL)
{
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
using namespace std;
#include "CSocketProtocol.h"
class 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
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 (buf==NULL || buflen==NULL)
{
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
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 CSckFactoryImp1
sp = new CSckFactoryImp2; //
ret = SckSendAndRec01(sp, in, inlen, out, &outlen);
if (ret != 0)
{
printf("func SckSendAndRec() err:%d \n", ret);
return ret;
}
delete sp; //想通过父类指针 释放所有的子类对象的资源 ..
cout<<"hello..."< system("pause");
return ret;
}
5.加密协议抽象类的定义
#pragma once
class 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
using namespace std;
#include "CEncDesProtocol.h"
class 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
using namespace std;
#include "HwEncDec.h"
#include "des.h"
int 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
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 CSckFactoryImp1
sp = 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; //想通过父类指针 释放所有的子类对象的资源 ..
cout<<"hello..."< system("pause");
return ret;
}
加解密的代码是des.h和des.c,可在前面“08文件操作”查看源代码。
8.将测试框架从函数形式升级为类的形式
#define _CRT_SECURE_NO_WARNINGS
#include
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 CSckFactoryImp1
sp = 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;
cout<<"hello..."< system("pause");
return ret;
}
无非就是将之前的全局函数封装在一个测试用的类里面,然后该测试类拥有socket和加解密协议的基类对象作为该测试类的成员变量。
结论:回调函数的本质:提前做了一个协议的约定(把函数的参数、函数返回值提前约定)
动态库升级为框架的编码实现
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、 动态库中可以缓存第三方函数的入口地址,也可以不缓存,两种实现方式。
案例总结
回调函数:利用函数指针做函数参数,实现的一种调用机制,具体任务的实现者,可以不知道什么时候被调用。
回调机制原理: