C++之纯虚函数和抽象类

纯虚函数和抽象类

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*a<<endl;;}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/2<<endl;;}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*b<<endl;;}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..."<<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”的访问不明确cout<<"hello..."<<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){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..."<<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);cout<<"Hello!"<<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、 厂商1(CSckFactoryImp1)实现CSocketProtocol、厂商2(CSckFactoryImp1)实现CSocketProtoco
5、 抽象加密接口(CEncDesProtocol)、加密厂商1(CHwImp)、加密厂商2(CCiscoImp)),集成实现业务模型
6、 框架(c语言函数方式,框架函数;c++类方式,框架类)

几个重要的面向对象思想
* 继承-组合(强弱)
* 注入
* 控制反转 IOC
* MVC
* 面向对象思想扩展aop思想:aop思想是对继承编程思想的有力的补充

实现步骤

  1. 定义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.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 <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 (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 <iostream>
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 <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 (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 <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; //想通过父类指针 释放所有的子类对象的资源 ..cout<<"hello..."<<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.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 <iostream>
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 <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; //想通过父类指针 释放所有的子类对象的资源 ..cout<<"hello..."<<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;cout<<"hello..."<<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、 动态库中可以缓存第三方函数的入口地址,也可以不缓存,两种实现方式。

案例总结

  • 回调函数:利用函数指针做函数参数,实现的一种调用机制,具体任务的实现者,可以不知道什么时候被调用。

  • 回调机制原理:

    • 当具体事件发生时,调用者通过函数指针调用具体函数
    • 回调机制将调用者和被调函数分开,两者互不依赖
    • 任务的实现 和 任务的调用 可以耦合 (提前进行接口的封装和设计)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/448357.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决: -bash: $‘\302\240docker‘: command not found

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 我只是运行 一条很简单的启动容器的命令&#xff0c;多次执行都报错&#xff0c;报错如题&#xff1a; -bash: $\302\240docker: comma…

【汽车取证篇】GA-T 1998-2022《汽车车载电子数据提取技术规范》(附下载)

【汽车取证篇】GA-T 1998-2022《汽车车载电子数据提取技术规范》&#xff08;附下载&#xff09; GA-T 1998-2022《汽车车载电子数据提取技术规范》标准—【蘇小沐】 总结 公众号回复关键词【汽车取证】自动获取资源合集&#xff0c;如链接失效请留言&#xff0c;便于…

解决: Client does not support authentication protocol requested by server; consider upgrading MySQL

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 在服务器上把 mysql 装好后&#xff0c;运行起来。 2. navicat 死活连接不上&#xff0c;在网上查说是要改数据库账号、密码什么的&…

C++之STL理论基础

1.基本概念 STL&#xff08;Standard Template Library&#xff0c;标准模板库)是惠普实验室开发的一系列软件的统称。虽然主要出现在C中&#xff0c;但在被引入C之前该技术就已经存在了很长的一段时间。 STL的从广义上讲分为三部分&#xff1a;algorithm&#xff08;算法&am…

解决maven打包报错:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、报错经历&#xff1a; 今天使用eclipse通过maven install打war包的时候&#xff0c;出现了下图所示的错误 二、问题分析&#xff1a…

STL之Vector

1.简介 vector是将元素置于一个动态数组中加以管理的容器。可以随机存取元素&#xff08;支持索引值直接存取&#xff0c;用[]操作符或at()方法&#xff0c;还支持迭代器方式存取&#xff09;。   vector尾部添加或移除元素非常快速。但是在中部或头部插入元素或移除元素比…

解决 : Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 执行 maven install 命令报错如题&#xff1a; Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:comp…

Docker 镜像 重命名

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 镜像改名命令格式&#xff1a; # 命令格式&#xff1a;docker tag 镜像id 仓库&#xff1a;标签或&#xff1a;docker tag 旧镜…

Java蓝桥杯02——第二题集锦:生日蜡烛、星期一、方格计数、猴子分香蕉

第二题 生日蜡烛(结果填空) 某君从某年开始每年都举办一次生日party&#xff0c;并且每次都要吹熄与年龄相同根数的蜡烛。 现在算起来&#xff0c;他一共吹熄了236根蜡烛。 请问&#xff0c;他从多少岁开始过生日party的&#xff1f; 请填写他开始过生日party的年龄数。 注意&a…

解决:Error response from daemon: Get https://index.docker.io/v1/search?q=openjdkn=25: dial tcp: looku

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 我只是想查一个 mysql 镜像。执行命令&#xff1a; docker search mysql 。报错如下&#xff1a; Error response from daemon…

安装 Git ( Windows、linux、Mac)

安装 Git 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 是时候动手尝试下 Git 了&#xff0c;不过得先安装好它。有许多种安装方式&#xff0c;主要分为两种&#xff0c;一种是通过编…

STL之函数适配器

1.理论知识 2.常用函数适配器 标准库提供一组函数适配器&#xff0c;用来特殊化或者扩展一元和二元函数对象。常用适配器是&#xff1a; 1绑定器&#xff08;binder&#xff09;: binder通过把二元函数对象的一个实参绑定到一个特殊的值上&#xff0c;将其转换成一元函数对象…

pyqt5 + pyinstaller 制作爬虫小程序

环境:mac python3.7 pyqt5 pyinstaller ps: 主要是熟悉pyqt5, 加入了单选框 输入框 文本框 文件夹选择框及日历下拉框 效果图: pyqt5 主程序文件 # -*- coding: utf-8 -*- # Author: Mehaei # Date: 2019-07-10 13:02:56 # Last Modified by: Mehaei # Last Modified time…

axios中出现两次请求,OPTIONS请求和GET请求

在项目中发现ajax中出现两次请求&#xff0c;OPTIONS请求和GET请求 查看到浏览器NetWork有两次请求&#xff0c;请求url一样&#xff1a; 查找原因是浏览器对简单跨域请求和复杂跨域请求的处理区别。 XMLHttpRequest会遵守同源策略(same-origin policy). 也即脚本只能访问相同协…

Linux 安装 配置 Maven

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1.需要提前安装JDK&#xff0c;并且配置环境变量 请参考&#xff1a;https://blog.csdn.net/jiangyu1013/article/details/84321146 2.…

[Git高级教程 (一)] 通过 Tag 标签回退版本修复 bug

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1 前言 本系列之所以取名”Git高级教程”&#xff0c;主要是教大家解决实际工作中遇到的问题&#xff0c;要求读者会基本的Git用法和命令…

Javascript 自定义输出

缘由 前段时间再看了一些javascript的学习资料,也写的一些demo,在输出的时候一般都用alert,但这个方法会打断函数运行,用起来不是很好.还有就是console.log这个方法,这种方法原来一直以为只能在FireFox上面才能用,现在才发现主流浏览器都支持.但我的这个插件已经写的差不多了,所…

uplift model学习笔记

一、解决的问题&#xff1a; 通常的 Propensity Model 和 Response Model 只是给目标用户打了个分&#xff0c;并没有确保模型的结果可以使得活动的提升最大化&#xff1b;它没有告诉市场营销人员&#xff0c;哪个用户最有可能提升活动响应&#xff1b; 因此&#xff0c;需要另…

设计模式之依赖倒置原则

在传统的过程式中&#xff0c;上层依赖于底层&#xff0c;当底层变化&#xff0c;上层也得跟着做出相应的变化。这就是面向过程的思想&#xff0c;弊端就是导致程序的复用性降低并且提高了开发的成本。 而面向对象的开发则很好的解决了这个问题&#xff0c;让用户程序依赖于抽象…

@Transactional 详解

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Transactional 是声明式事务管理 编程中使用的注解 1 .添加位置 1&#xff09;接口实现类或接口实现方法上&#xff0c;而不是接口类中…