工厂模式 multiple definition 多重定义 即重复定义 找不到/dev/vide0设备
这里写目录标题
- 一.设计模式
- 设计模式的引入
- 类和对象
- 工厂模式-简单工厂模式
- 使用结构体
- 二.使用工厂模式进行编程
- cat.c 文件
- main.c函数
- moban.h 文件
- 三.工厂模式搭建
- 四.mjpg-streamer的安装
- 安装实现
- 五.找不到/dev/vide0设备
- 6.智能家居设计实现
- 文件介绍
- 设备工厂的使用
- 灯光的实现
- camera的实现
- 指令工厂
- 语音识别
- main函数
一.设计模式
设计模式的引入
设计模式是代码设计经验的总结,稳定拓展性强
设计模式是代码经验的总结,稳定,拓展性强,一共23种
C 面向的是过程,是一种不太好的面向对象的过程
java 面向对象
工厂模式是表示面向对象的编程
分成不同的对象分别进行编程
类和对象
类是一种用户定义的引用的数据类型,也称类类型;结构体对象 类的一种具象
工厂模式-简单工厂模式
对象本身所具有的职责 记录对象的一些信息和行为
创建对象的职责
使用对象的职责工厂模式是为了将对象的创建和使用分离,也使得系统更加符合“单一职责原则”,
有利于对功能的复用和系统的维护,
防止用来实例化一个类的数据和代码在多个类中到处都是,
可以将有关创建的知识搬移到一个工厂类中。简单工厂模式(Simple Factory Pattern):定义一个工厂类,
它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。
因为在简单工厂模式中用于创建实例的方法是静态(static)方法,
因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节
使用结构体
struct moban
{int changdu;int jiadu; //成员属性char *name;void (*peat)(); //成员方法void (*peatb)();
};struct animal dog;
struct animal cat;
struct animal person;//这些就是对象
void catpeat()
{}
使用该结构体的时候可以直接使用该结构体的几个参数
struct moban cat={.name="Tom",.peat=catpeat,.peatb=catpeatb
};
这样就可以单独使用其中的某几个参数
void (*peat)();在结构体中定义的是一个函数指针,它指向的是一个函数
因此在结构体进行赋值的时候,它指向的就是上面进行定义的catpeat这个函数
二.使用工厂模式进行编程
工厂模式即创建多个.c工程 分别进行编程
cat.c 文件
#include "moban.h"
void catpeatb()
{printf("cat nono \n");
}
void catpeat()
{printf("cat eat fish\n");
}struct moban cat={.name="Tom",.peat=catpeat,.peatb=catpeatb
};
//使用头插法插入到链表当中
struct moban *putCatLink(struct moban *head)
{if(head==NULL){head=&cat;return head;}else{cat.next=head;head=&cat;return head;}
}
dog.c 文件
和 person.c文件
main.c函数
#include "moban.h"//使用的头文件包含在自己书写的头文件中
//寻找我们要找的链表的信息
struct moban *mobanfindnext(char *str,struct moban *head)
{struct moban *phh;phh=head;if(phh==NULL){printf("kong\n");return NULL;}else{while(phh != NULL){if(strcmp(str,phh->name)==0){return phh;}phh=phh->next;}}return NULL;
}int main()
{char str[128]={'\0'}; //输入的namestruct moban *head=NULL;struct moban *findnext;//找到的节点存放的位置head=putCatLink(head);head=putDogLink(head);head=putPersonLink(head);while(1){printf("input Tom da huang supeng\n");gets(str);findnext=mobanfindnext(str,head);if(findnext!=NULL){printf("name :%s\n",findnext->name);findnext->peat();findnext->peatb();}memset(str,'\0',sizeof(str));}return 0;
}
moban.h 文件
#include <stdio.h>struct moban
{int a;int b;char *name;void (*peat)();void (*peatb)();struct moban *next;};
//因为主函数调用这些函数需要知道位置
struct moban *putCatLink(struct moban *head);
struct moban *putDogLink(struct moban *head);
struct moban *putPersonLink(struct moban *head);
三.工厂模式搭建
使用指令工厂和控制工厂进行数据的处理
四.mjpg-streamer的安装
安装实现
sudo apt-get update #更新软件列表
sudo apt-get upgrade #更新软件
- 可以不用
sudo apt-get install subversion #Subversion是一个自由开源的版本控制系统
sudo apt-get install libjpeg8-dev #JPEG支持库sudo apt-get install imagemagicksudo apt-get install libv4l-dev #4l是小写"L"sudo apt-get install cmake #下载编译工具
sudo apt-get install git
git clone https://github.com/jacksonliam/mjpg-streamer.git
cd mjpg-streamer/mjpg-streamer-experimental #进入下载目录后进入左侧路径
7.编译
make all
sudo make install
uvc 是USB的
raspicam是树莓派的摄像头硬件设备
1.进入到start.sh里面 看到
#./mjpg_streamer -i "./input_uvc.so" -o "./output_http.so -w ./www"
将里面的input_uvc改成input_raspicam
./mjpg_streamer -i "./input_raspicam.so" -o "./output_http.so -w ./www"
9.修改完成后 使用指令
sudo raspi-config
进入设置界面后 点击 interfacing Optians
选择camera之后 重启设备
10.进入设备之后 进入到文件夹中使用
./start.sh 将树莓派的摄像头启动
11.在浏览器中输入 http://IP地址:8080
进入即可
点击页面左侧,Stream栏,显示监视画面
五.找不到/dev/vide0设备
树莓派CSI摄像头安装完成后,用raspivid和raspistill指令拍照,录像都没问题,但是ls /dev/video0的时候就显示没有这个设备
解决方案:
在/etc/modules的最后,加上:
bcm2835-v4l2
重启下,ls -l /dev/video0,应该能看到了。
原理:
链接: xxxxxxx.
,这里说了很多关于启动的问题,其中Raspberry Pi camera module这一章节就是说如何起camera。
树莓派中的camera module是放在/boot/目录下以固件的形式加载的,不是一个标准的v4l2的摄像头驱动,所以加载起来之后会找不到/dev/video0的设备节点,这是因为这个驱动是在底层的,v4l2这个驱动框架还没有加载,所以要在/etc/modules里面添加一行bcm2835-v4l2
6.智能家居设计实现
使用到的文件 以及工厂模式的实现
文件介绍
controlDevice.h 设备控制的工厂
livingroomLight.c 卧室灯
restaurantLight.c 厨房灯
upstairLight.c 二楼灯
restroomLight.c 厕所灯
cameraKey.c 进行人脸识别的按键
camera.c 人脸识别
fire.c 火焰传感器文件inputCommand.h 指令工厂
socketControl.c socket套接字文件
voiceControl.c 语音识别的文件//usartControl.c
ben.jpg 验证人脸识别的图片
filex 打开监控所需的文字
include.h 所需的全部头文件
//key.c
main.c 主函数
设备工厂的使用
#ifndef __CONTROLDEVICE_H
#define __CONTROLDEVICE_H
#include "include.h"
struct Devices
{char deviceName[128]; //设备名int status; //设备当前引脚状态int pin; //设备引脚int (*open)(int pin);//打开引脚int (*close)(int pin);//关闭int (*deviceInit)(int pin);//设备初始化int (*readStatus)(int pin);//读取引脚状态int (*changeStatus)(int status);//改变引脚的状态int (*curlPostUrl)(char *filename);//人脸识别传递的文件struct Devices* next;
};struct Devices *addRestaurantLightToDeviceLink(struct Devices *phead);//房
struct Devices *addRestroomLightToDeviceLink(struct Devices *phead);//厕所
struct Devices *addLivingroomLightToDeviceLink(struct Devices *phead);//卧室
struct Devices *addUpstairLightToDeviceLink(struct Devices *phead);//二楼
struct Devices *addFireToDeviceLink(struct Devices *phead);//火灾
struct Devices *addCameraKeyToDeviceLink(struct Devices *phead);//摄像头拍照
struct Devices *addCameraToDeviceLink(struct Devices *phead);//摄像头
灯光的实现
#include "controlDevice.h"int upstairLightOpen(int pin)
{digitalWrite(pin,LOW);
}
int upstairLightClose(int pin)
{digitalWrite(pin,HIGH);}
int upstairLightInit(int pin)
{pinMode(pin,OUTPUT);digitalWrite(pin,HIGH);}
int upstairLightChangeStatus(int status)
{printf("jj\n");}
struct Devices upstairLight={.deviceName="upstairLight",.open=upstairLightOpen,.pin=1,.close=upstairLightClose,.deviceInit=upstairLightInit,.changeStatus=upstairLightChangeStatus
};struct Devices *addUpstairLightToDeviceLink(struct Devices *phead)
{if(phead==NULL){phead=&upstairLight;return phead;}else{upstairLight.next=phead;phead=&upstairLight;return phead;}
}
在整个工厂模式的使用过程中使用的基本都是函数指针 在定义的时候open close等函数就是一个函数指针 在调用的时候指向被指向的函数的地址原理类似于 int add(int a,int b){return a+b;}现在在main函数中进行调用的时候,首先需要定义一个函数的指针int (*padd)(int a,int b);padd=add;//让该函数指针的地址指向上面的普通函数的地址//从而进行函数的调用padd(1,2);
camera的实现
#include "controlDevice.h"
#include <curl/curl.h>char str[1024]={'\0'};
//回调函数
size_t readData(void *ptr, size_t size, size_t nmemb, void *stream)
{memset(str,'\0',1024);strncpy(str,ptr,1024);printf("=================get data=================\n");printf("%s\n",str);printf("==========================================\n");}
char *base64process(char *filename)
{int fd;char cmd[128]={'\0'};//指令的初始化char *data;sprintf(cmd,"base64 %s > file1",filename); //执行的是base64 照片名 >file1 //照片的base64流放在图片中进行保存system(cmd);fd = open("./file1",O_RDWR);int filelong = lseek(fd,0,SEEK_END);lseek(fd,0,SEEK_SET);printf("%d\n",filelong);data=(char *)malloc(filelong+1);memset(data,'\0',filelong+1);read(fd,data,filelong); //读取出来close(fd);system("rm -f file1");return data;}int cameraCurlPostUrl(char *filename)
{CURL *curl;CURLcode res;char *postString;char *img1=base64process(filename);char *img2=base64process("./ben.jpg");char *key="";char *secret="";int typeId =21;char *format ="xml";postString=(char *)malloc(strlen(secret)+strlen(key)+strlen(img1)+strlen(img2)+124);sprintf(postString,"&img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s",img1,img2,key,secret,typeId,format);curl = curl_easy_init();if (curl){curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt"); // 指定cookie文件curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postString); // 指定post内容curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do"); // 指定url(即要访问的网站)curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, readData); //将返回的http头输出到fp指向的文件res = curl_easy_perform(curl);//请求的结果printf("OK=%d\n",res);curl_easy_cleanup(curl);}if(strstr(str,"是")!=NULL){return 1;}else{return 0;}
}int cameraInit(int pin)
{pinMode(pin,OUTPUT);
}//创建结构体
struct Devices camera={.deviceName="camera",.pin=23,.deviceInit=cameraInit,.curlPostUrl=cameraCurlPostUrl
};
struct Devices *addCameraToDeviceLink(struct Devices *phead)
{if(phead==NULL){return &camera;}else{camera.next=phead;phead=&camera;return phead;}
}
上面使用的是curl 库 连接的翔云人工智能平台使用post请求 进行数据的传输 将post要发送的数据通过body体进行传递指定要传输的url 即访问的网站传递过后调用回调函数,将回调后产生的数据显示出来,保存在字符串中通过判断字符中是否含有 “是” 判断是否人脸识别成功
指令工厂
#ifndef __INPUTCOMMAND_H
#define __INPUTCOMMAND_H#include "include.h"
struct inputCommand
{int fd;//文件描述符char devicename[64];//指令设备的地址char commandName[128]; //指令设备的名称char command[32];//传输的内容char port[16];//端口号char ipAddress[32];//ip地址int (*Init)(struct inputCommand *command,char *ip,char *port);int (*getCommand)(struct inputCommand *command);char log[1024];struct inputCommand * next;};struct inputCommand* addvoiceInputCommandToCommandLink(struct inputCommand *phead2);//声音
struct inputCommand* addsocketInputCommandToCommandLink(struct inputCommand *phead2);//socket
#endif /*__INPUTCOMMANT_H */
语音识别
语音识别使用的是串口的接收 RX
读取语音识别芯片发送过来的数据
#include "inputCommand.h"int voiceGetCommand(struct inputCommand *voiceInputCommand)
{int nread;memset(voiceInputCommand->command,0,sizeof(voiceInputCommand->command));nread=read(voiceInputCommand->fd,voiceInputCommand->command,sizeof(voiceInputCommand->command));return nread;//返回读取到的数据大小 进行判断是否读取到了数据
}
int voiceInit(struct inputCommand *voiceInputCommand,char *ip,char *port)
{int fd;wiringPiSetup();fd = serialOpen(voiceInputCommand->devicename,9600);if(fd==-1){exit(-1);}voiceInputCommand->fd=fd;return fd; }struct inputCommand voiceInputCommand ={.fd=0,.devicename="/dev/ttyAMA0",.commandName="voice",.command={'\0'},.Init=voiceInit,.getCommand=voiceGetCommand,.log={'\0'},.next=NULL
};struct inputCommand* addvoiceInputCommandToCommandLink(struct inputCommand *phead2)
{if(phead2==NULL){return &voiceInputCommand;}else{voiceInputCommand.next=phead2;phead2=&voiceInputCommand;return phead2;}}
main函数
将所有的设备通过链表的方式传接起来
并创建线程池,进行不同功能的实现
#include "controlDevice.h"
#include "inputCommand.h"
#include <pthread.h>
//将两个链表的头定义成全局变量
struct Devices *phead = NULL;
struct inputCommand *phead2 =NULL;
struct inputCommand *socketInput=NULL;//socket的链表节点
struct inputCommand *voiceInput=NULL;//串口的
int c_fd;//socket的accept函数产生的文件描述符/*遍历链表头插法遍历链表 head的节点的名字不等于要查找的 则到下一个节点*/
struct Devices *findDevices(struct Devices *phead,char *name)
{struct Devices *p=phead;while(p!=NULL){if(strcmp(p->deviceName,name)==0){return p;}p=p->next;}return NULL;
}
struct inputCommand *findInputCommand(struct inputCommand *phead2,char *name)
{struct inputCommand *p=phead2;while(p!=NULL){if(strcmp(p->commandName,name)==0){return p;}p=p->next;}return NULL;
}
void deviceInits(struct Devices *phead)
{struct Devices *p=phead;while(p!=NULL){p->deviceInit(p->pin);p=p->next;}
}
//process
void process_KT(struct inputCommand* processInputCommand)
{printf("process\n");if(!strncmp("open",processInputCommand->command,4)){printf("1\n");serialPuts(voiceInput->fd,"open\n");}else{printf("2\n");serialPuts(voiceInput->fd,"close\r\n");}}
//声音处理函数
void process_LED(struct inputCommand* processInputCommand)
{struct Devices *tmp=NULL;if(strstr(processInputCommand->command,"ws")!=NULL){struct Devices *tmp=findDevices(phead,"livingroomLight");printf("name:%s\n",tmp->deviceName);if(!strncmp("open",processInputCommand->command,4)){tmp->open(tmp->pin);}else{tmp->close(tmp->pin);}}else if(strstr(processInputCommand->command,"el")!=NULL){struct Devices *tmp=findDevices(phead,"upstairLight");printf("name:%s\n",tmp->deviceName);if(!strncmp("open",processInputCommand->command,4)){tmp->open(tmp->pin);}else{tmp->close(tmp->pin);}}else if(strstr(processInputCommand->command,"cs")!=NULL){struct Devices *tmp=findDevices(phead,"restroomLight");printf("name:%s\n",tmp->deviceName);if(!strncmp("open",processInputCommand->command,4)){tmp->open(tmp->pin);}else{tmp->close(tmp->pin);}}}//声音线程函数
void *voice_pthread(void *data)
{int n_read;//1.在链表中进行寻找voice的节点voiceInput = findInputCommand(phead2,"voice");if(voiceInput==NULL){printf("find voiceInputCommand error\n");pthread_exit(NULL);//退出线程}else{//2.进行voice的初始化if(voiceInput->Init(voiceInput,NULL,NULL)<0){printf("voice init error\n");pthread_exit(NULL);}else{printf("voice init success\n");}//3.进行voice信息的读取 并进行打印数据while(1){n_read = voiceInput->getCommand(voiceInput);if(n_read==0){printf("no voice\n");}else{printf("voice :%s\n",voiceInput->command);process_LED(voiceInput);}}}}
//socket的处理函数
void *process_pthread(void *data)
{int n_read=0;printf("process\n");memset(&socketInput->command,0,sizeof(socketInput->command));n_read = read(c_fd,socketInput->command,sizeof(socketInput->command));if(n_read>0){printf("nget :%s\n",socketInput->command);if(strstr(socketInput->command,"kt")!=NULL){process_KT(socketInput);}else{process_LED(socketInput);}}else{printf("没有数据\n");exit(-1);}
}
void *socket_pthread(void *data)
{pthread_t processPthread;struct sockaddr_in c_addr;int s_fd;int clong = sizeof(struct sockaddr_in);memset(&c_addr,0,sizeof(struct sockaddr_in));//1.在链表中进行寻找socket的节点socketInput = findInputCommand(phead2,"socket");if(socketInput==NULL){printf("find socketInput error\n");pthread_exit(NULL);}else{//2.进行socket的初始化socketInput->Init(socketInput,NULL,NULL);printf("socket OK\n");while(1){//3.创建等待连接printf("wait\n");c_fd=accept(socketInput->fd,(struct sockaddr *)&c_addr,&clong);if(c_fd>0){printf("连接端口的IP地址是 :%s\n",inet_ntoa(c_addr.sin_addr));//打印连接的Ip地址//3.启动一个新的线程进行数据的交互pthread_create(&processPthread,NULL,process_pthread,NULL);}}}
}
void *fire_pthread(void *data)
{struct Devices *fireInput=NULL;pinMode(24,OUTPUT);digitalWrite(24,LOW);fireInput = findDevices(phead,"fire");if(fireInput==NULL){printf("find fireInput error\n");pthread_exit(NULL);}else{//对fire进行初始化fireInput->deviceInit(fireInput->pin);printf("fire OK\n");while(1){//读取当前引脚的状态值delay(1000);//延时5sint status;status=fireInput->readStatus(fireInput->pin);if(status==0){digitalWrite(24,HIGH);printf("fire xxxxx\n");}else{digitalWrite(24,LOW);}}}
}
void curl_process(int i)
{i=1;digitalWrite(23,LOW);char cmd1[16]={'\0'};sprintf(cmd1,"image%d.jpg",i);char cmd[128]={'\0'};sprintf(cmd,"wget http://192.168.8.135:8080/?action=snapshot -O %s",cmd1);system(cmd);delay(1000);struct Devices *cameracurlInput=NULL;cameracurlInput=findDevices(phead,"camera");if(cameracurlInput==NULL){printf("cameracurlInput find error\n");}else{int dataxx=cameracurlInput->curlPostUrl(cmd1);system("rm image1.jpg");if(dataxx==1){digitalWrite(23,HIGH);}else{digitalWrite(23,LOW);}}}
void *camera_pthread(void * data)
{struct Devices *cameraInput=NULL;cameraInput=findDevices(phead,"cameraKey");if(cameraInput==NULL){printf("cameraInput find error\n");pthread_exit(NULL);}else{cameraInput->deviceInit(cameraInput->pin);printf("camera OK\n");int i=0;while(1){int status;delay(5000);status=cameraInput->readStatus(cameraInput->pin);if(status==1){i++;curl_process(i);}}}
}
int main()
{if(wiringPiSetup()==-1){return -1;}int fdx;char *str;//创建线程进行pthread_t voicePthread;//声音的线程pthread_t socketPthread;//socket的线程pthread_t firePthread;//火灾的线程pthread_t cameraPthread;//摄像头的线程//主函数char name[128]={'\0'};//指令//指令工厂初始化 voice socketphead2=addvoiceInputCommandToCommandLink(phead2);phead2=addsocketInputCommandToCommandLink(phead2);//设备工厂初始化 phead=addRestaurantLightToDeviceLink(phead);phead=addRestroomLightToDeviceLink(phead);phead=addLivingroomLightToDeviceLink(phead);phead=addUpstairLightToDeviceLink(phead);phead=addFireToDeviceLink(phead);phead=addCameraKeyToDeviceLink(phead);phead=addCameraToDeviceLink(phead);//初始化函数deviceInits(phead);//创建线程池/*** int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);* 线程中不建议进行参数的传递 ,可以设置成全局变量进行使用*///1.声音的线程创建 不进行传递参数pthread_create(&voicePthread,NULL,voice_pthread,NULL);printf("OK\n");//2.socket的线程的创建 不进行传递参数pthread_create(&socketPthread,NULL,socket_pthread,NULL);//3.fire 的线程的创建 不进行参数的传递pthread_create(&firePthread,NULL,fire_pthread,NULL);//4.camera摄像头的线程创建 不进行参数传递pthread_create(&cameraPthread,NULL,camera_pthread,NULL);//5.直接在主线程中打开摄像头的监控fdx=open("./filex",O_RDWR);int filelong = lseek(fdx,0,SEEK_END);lseek(fdx,0,SEEK_SET);str = (char *)malloc(filelong+1);memset(str,'\0',filelong);read(fdx,str,filelong);system(str);while(1);return 0;}
1.通过链表的操作分别将两个工厂的文件联系起来2.创建线程池,进行数据的处理 线程里不建议进行参数的传递2.1 声音的线程在使用声音节点,需要在指令链表中找到声音的节点,通过设备名其次将数据进行处理2.2 socke线程socket线程可以进行空调和LED灯光的控制2.3 火灾线程使用火焰传感器检测传感器从高电平变为低电平触发火焰传感器进行报警2.4 人脸识别当按键按下之后,会触发读取数据的响应,系统会首先会调用指令拍去当前要进行人脸识别的人的头像wget http://192.168.8.135:8080/?action=snapshot -O image1.jpg获得图像后,调用curl进行人脸识别 识别结果通过后,系统返回1 打开门3.打开监控功能监控的指令存放在filex文件中,将读取到的内容进行执行就能获得,打开监控
工厂模式 multiple definition 多重定义 即重复定义 找不到/dev/vide0设备相关推荐
- 问题记录:multiple definition of `xxxx` 问题解决 struct定义类的error:“unknown type name“
一.multiple definition of xxxx 问题解决 问题背景 我在一个头文件里面定义了一个变量,并赋予初值,然后再两个.c 文件里引入了这个头文件,结果就报错 multiple de ...
- 【Java设计模式】简单学抽象工厂模式——你好,微信还是支付宝
目录 说明 实现方式 自问自答 其他链接 说明 五大创建型模式之一,其他还有单例模式.原型模式.建造者模式.工厂模式. 抽象工厂模式(Abstract Factory Pattern):定义了一个in ...
- GOF23设计模式(创建型模式)工厂模式
目录: 一:工厂模式的核心本质 二:关于面向对象的六大基本原则 三:工厂模式的三大类详解(代码示例,详细分析) 首先,上咱本GOF23所有工厂模式的分类表格!!! 创建型模式 单例模式.工厂模式.抽象 ...
- C++模式学习------工厂模式
工厂模式属于创建型模式,大致可以分为简单工厂模式.抽象工厂模式. 简单工厂模式,它的主要特点是需要在工厂类中做判断,从而创造相应的产品. 1 enum PTYPE 2 { 3 ProdA = 0, 4 ...
- 结合案例深入解析:抽象工厂模式
一.基本概念 当涉及到产品族的时候,就需要引入抽象工厂模式了. 每一个模式都是针对一定问题的解决方案.抽象工厂模式与工厂方法模式的最大区别就在于,工厂方法模式针对的是一个产品等级结构:而抽象工厂模式则 ...
- 大话设计模式Python实现-简单工厂模式
简单工厂模式(Simple Factory Pattern):是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类. 下面使用简单工厂模式实现一个简单的四则运算 1 #!/us ...
- 设计模式学习总结——工厂模式
在我们平常创建对象的时候,都是通过关键字 new 来实现的,例: Class A = new A() . 在一些情况下,要创建的对象需要一系列复杂的初始化操作,比如查配置文件.查数据库表.初始化成员对 ...
- 设计模式C++实现——工厂模式
工厂模式属于创建型模式,主要可分为三类,简单工厂.工厂方法.抽象工厂.工厂模式规定,无论是工厂函数,工厂类的成员函数,返回的对象都必须位于heap. 有三点需要特别注意: 堆对象 三种工厂模式都属于创 ...
- 设计模式之工厂模式,史上最强,不服来辩!
设计模式是对大家实际工作中写的各种代码进行高层次抽象的总结,如果设计模式没学会,抽象能力肯定就不会太强.常见的设计模式有 23 种,今天我们只聊最简单的工厂模式. 工厂模式是属于创建型模式的,通过工厂 ...
最新文章
- MonoRec:无需激光雷达,只需单个相机就可以实现三维场景的稠密重建
- python3.6使用pygal模块不具交互性,图片不能显示数据
- mysql 表名 参数化_我可以在准备好的语句中参数化表名吗?
- 进程间通信——自定义消息方式实现(SetWindowsHookEx)
- String 重载 + 原理分析
- Loj #6089. 小 Y 的背包计数问题
- 【干货】分享总结:MySQL数据一致性
- SpringMVC 异步交互 AJAX 文件上传
- python自带的shell、其性能优于ipython吗_根据强化的性质和目的可以分成()。 A.自然强化物和人为的近似强化物B.积极强化和消极...
- Num37 spring 事务 ssh整合
- sicily 1443 Printer Queue
- Linux里如何查找文件内容
- 3.1 广义线性模型 And XGBoost
- 低压差线性稳压器MPQ2013A-AEC1品牌MPS国产替代
- Matebook xpro2019指纹驱动不可用
- git commit之后,回退撤销commit
- 基于阿里云IOT Studio和STM32的电机远程监测设计
- mysql药品库管理项目简介_MySQL数据库项目化教程简介,目录书摘
- python模拟点击后获取状态码_Python获取网页状态码
- 关于安卓一键分享的,急求帮助!
热门文章
- 为iPhone6设计自适应布局(一)
- SpringBoot+Vue+Jpa+Redis实现单点登录(一处登录,另一处退出登录)
- android log4j slf4j,slf4j、log4j 的使用
- 前后端联调,比Postman更好用的国产接口调试工具:Apipost
- 讲师加油站 | 002 | 培训师的六种控场技巧,赶紧get起来!
- 基于Java的网络兼职平台系统的设计与实现(论文+程序设计+数据库文件)
- [嵌入式框架][nrf52820][nrf52840] 硬件USB_HID
- [译] 什么是模块化 CSS?
- html 锚点 中文,html怎么设置锚点
- TCP会话劫持攻击实验