一.工厂模式简介
在面向对象编程中,简单工厂模式是最常用的设计模式之一。所谓简单工厂模式就是借助面向对象语言的多态特性,根据不同的输入要求输出实例化后的具体操作子类指针。通俗来讲,就是根据输入需求加工出对应输出子类对象。
在C语言中本没有面向对象的实现机制,更没有多态的实现方法,但我们仍可以按照面向对象的编程思想来进行开发。比如可以借助结构体将变量和函数指针封装在一起实现封装;通过结构体嵌套实现继承(具体实现可参考我之前的博客);借助二重指针实现多态;虽说C语言实现上较C++等面向对象语言麻烦些,但编程的思想是通用的,毕竟linux内核源码中使用了大量的面向对象编程思想,精妙之处,溢于言表。
二.借助二重指针实现简单工厂模式
简单介绍:下面代码借助了二重指针按照简单工厂模式实现了一个计算器,其核心思想就在于对二重指针的运用,这里简单解释为:通过传入函数指针的指针,从而实现对函数指针的明确指向(也可以理解为实例化)。传入二重指针实际上改变的并不是该指针变量本身的地址,而是改变其指向的地址,因此改变之后按照函数调用的方式对其解引用的结果自然也就不同了。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//add函数
int add(int a,int b)
{
return a+b;
}
//sub函数
int sub(int a,int b)
{
return a-b;
}
//mul函数
int mul(int a,int b)
{
return a*b;
}
//dev函数
int dev(int a,int b)
{
if(b == 0)return 0; //注意对除法操作的警惕
return a/b;
}
/**
* @brief 操作工厂,会将输入的函数指针指向不同的实现函数(经过工厂加工,函数指针实例化为不同的函数对象)
*
* @param pfunc:指针变量,用来指向执行的函数(在该函数中会被修改)
* oper: '+','-','*','/'运算符
*
* @return void
*
*/
void factory(int (**pfunc)(int ,int ),char oper)
{
switch(oper)
{
case '+':
*pfunc = add; //指针指向add函数
break;
case '-':
*pfunc = sub; //指针指向sub函数
break;
case '*':
*pfunc = mul; //指针指向mul函数
break;
case '/':
*pfunc = dev; //指针指向dev函数
break;
default:
*pfunc = NULL; //指针指向NULL
break;
}
}
//输入1 2 3 4分别代表指向+ - * /操作
int main(int argc,char *argv[])
{
int result = 0;
int (*pfunc)(int,int) = NULL; //定义函数指针pfunc
if(argc !=2)
{
printf("usage:%s 1 2 3 4\r\n",argv[0]);
return -1;
}
switch(atoi(argv[1]))
{
case 1:
factory(&pfunc,'+'); //将指向函数的指针的指针传入,函数指针pfunc会指向add函数
break;
case 2:
factory(&pfunc,'-'); //将指向函数的指针的指针传入,函数指针pfunc会指向sub函数
break;
case 3:
factory(&pfunc,'*'); //将指向函数的指针的指针传入,函数指针pfunc会指向mul函数
break;
case 4:
factory(&pfunc,'/'); //将指向函数的指针的指针传入,函数指针pfunc会指向dev函数
break;
default:
printf("输入的第二个参数有误,请重新输入\r\n");
return -1;
break;
}
//根据函数指针执行具体的函数
result = (*pfunc)(2,3);
printf("result = %d\r\n",result); //输出结果
return 0;
}
三.执行结果
该函数是在linux环境下指执行的:
1.+测试
输入:./a.out 1
输出:5
2.+测试
输入:./a.out 2
输出:-1
3.+测试
输入:./a.out 3
输出:6
4.+测试
输入:./a.out 4
输出:0