简单工厂模式:
typedef enum
{
A,
B
} productType;
class product
{
public:
product(){};
~product(){};
virtual void show()=0;
};
class productA : public product
{
public:
productA(){};
~productA(){};
void show()
{
cout<<"productA"<
};
class productB : public product
{
public:
productB(){};
~productB(){};
void show()
{
cout<<"productB"<
};
class Factory
{
public:
Factory(){};
~Factory(){};
product * createProduct(int type)
{
product * pl = NULL;
switch(type)
{
case(A): pl = new productA(); break;
case(B): pl = new productB(); break;
default:
break;
}
return pl;
}
};
void main()
{
Factory a;
a.createProduct(A)->show();
a.createProduct(B)->show();
cin.get();
}
定义一个工厂,里面生产若干产品,通过swtich(case)输入参数来确定生产那种产品,缺点是可扩展性不强,增加产品时需要修改factory这个类,好的设计模式要求只扩展而不修改。
写的时候发现报错,原因是我写factory基类时忘了加public,我查了下,未定义权限时,因为类的默认权限都是private,导致子类构造时无法调用到父类的构造函数导致报错
另外还有临时变量的自动释放问题,为什么我createProduct返回的这个Product的指针可以,不是栈区的应该被释放了么,看下面的例子:
char* getStr(void)
{
//char* p = new char[20];
char p[] ="hello";
printf("p:%p ",p);
return p;
};
char* getStr2(void)
{
char p1[] ="hello2";
printf("p1:%p \n",p1);
return p1;
};
int* getStr3(void)
{
int a = 8;
int *p =&a;
printf("p2:%p ",p);
return p;
};
char* getStr4(void)
{
char *p1 ="hello2";
printf("p3:%p \n",p1);
return p1;
};
void main()
{
char* str1 = getStr();
char* str2 = getStr2();
int* str3 = getStr3();
char* str4 = getStr4();
printf("%p:%s..\n...%p:%s \n",str1,str1,str2,str2);
printf("%p:%d..\n...%p:%s \m",str3,*str3,str4,str4);
system("pause");
}
debug:
release:
因此,我们可以这样理解,栈区资源的释放实际是临时指针的释放,不指向这块内存,从而可以使得这块内存被其他的使用。在release中栈内存内内容不发生变化,在debug版本中指针内容销毁(不知道为什么)。而返回值另存到寄存器中,实际是否能得到,还得看变量存储的位置,getStr4()这样写一定能取到值,是因为char p1[] ="hello2";这样定义字符串存储在栈区,随着内存销毁即便得到了这个栈地址,地址内的内容也已经被销毁,而char *p1 ="hello2";这样定义“hello2”存放在常量区,从地址值也可以看出,随着临时指针销毁(无法再获取p,但这个函数能将这个栈内指针转存到其他寄存器中),这个存放在常数区的“hello2”并不会被销毁,事实上这个指针指向堆区地址也能得到取到指针内容(也就是上述我们可以得到product指针内容的原因)。
工厂方法模式:
为了不修改factory,于是产生了工厂方法模式,一个工厂只生成一种产品,要再生产另一种时,那么产生一个新的工厂即可。
typedef enum
{
A,
B
} productType;
class product
{
public:
product(){};
~product(){};
virtual void show()=0;
};
class productA : public product
{
public:
productA(){};
~productA(){};
void show()
{
cout<<"productA"<
};
class productB : public product
{
public:
productB(){};
~productB(){};
void show()
{
cout<<"productB"<
};
class Factory
{
public:
Factory(){};
~Factory(){};
virtual product* create()=0;
};
class FactoryA:public Factory
{
public:
FactoryA(){};
~FactoryA(){};
product* create()
{
return new productA();
}
};
class FactoryB:public Factory
{
public:
FactoryB(){};
~FactoryB(){};
product* create()
{
return new productB();
}
};
void main()
{
Factory * FA = new FactoryA();
Factory * FB = new FactoryB();
FA->create()->show();
FB->create()->show();
cin.get();
}
上面基本比较简单,涉及c++的多态,用父类指针去管理子类对象,new出来时右边实际是子类指针,为什么子类指针可以转换为父类指针相反却不可以呢,子类对象其实包含父类的内容,所以是一个更大的概念,我们可以这么想,大的转换成小的只需要裁剪即可,而小的转换成大的实际是不可能的。
那还有强制的需求,需要一个工厂生产多个产品,那只能用第3种工厂模式
抽象工厂模式:
实际是第二种的扩展,如下:
class product
{
public:
product(){};
~product(){};
virtual void show()=0;
};
class productA1 : public product
{
public:
productA1(){};
~productA1(){};
void show()
{
cout<<"productA1"<
};
class productA2 : public product
{
public:
productA2(){};
~productA2(){};
void show()
{
cout<<"productA2"<
};
class productB2 : public product
{
public:
productB2(){};
~productB2(){};
void show()
{
cout<<"productB2"<
};
class productB1 : public product
{
public:
productB1(){};
~productB1(){};
void show()
{
cout<<"productB1"<
};
class Factory
{
public:
Factory(){};
~Factory(){};
virtual product* create1()=0;
virtual product* create2()=0; //若超过2种最开始就做好createN()
};
class FactoryA:public Factory
{
public:
FactoryA(){};
~FactoryA(){};
product* create1()
{
return new productA1();
}
product* create2()
{
return new productA2();
}
};
class FactoryB:public Factory
{
public:
FactoryB(){};
~FactoryB(){};
product* create1()
{
return new productB1();
}
product* create2()
{
return new productB2();
}
};
void main()
{
Factory * FA = new FactoryA();
Factory * FB = new FactoryB();
FA->create1()->show();
FA->create2()->show();
FB->create1()->show();
FB->create2()->show();
cin.get();
}
这些个例子网上也能找到,自己写写练习一下