设计模式:工厂模式(续:虚构造函数和抽象工厂)

在之前的《设计模式:工厂模式》中记录了两种用于创建派生类对象的工厂模式,第一种模式直接使用基类的静态成员函数来创建派生类的对象,在该静态成员函数中直接调用了派生类的构造函数,第二种模式是使用基类工厂的静态成员函数,通过基类工厂中保存的各派生类工厂来创建派生类对象,派生类工厂是派生类的嵌套类,相当于为派生类量身定做的专属工厂,这些专属工厂的存在使得基类工厂不必了解创建派生类对象的细节。今天主要记录另外两种工厂模式:虚构造函数和抽象工厂。虚构造函数模式与前两种工厂模式不同,在前两种工厂模式中,基类是基类,派生类是派生类,在虚构造函数模式中,基类虽然还是基类,但是基类的行为却是派生类的行为,所以从作用效果上看,基类貌似就是派生类了,下面看一个简单的例子:

class Base {
	Base *p;
protected:
	Base() { p = NULL; }
public:
	Base(const string &str);
	~Base();
	virtual void func() { p->func(); }
};
这是基类的定义,基类中有一个基类的指针:p ,这个指针最终将指向一个派生类对象,注意到在基类的成员函数func()中,通过p调用了派生类的func(),所以基类的行为就是派生类的行为,下面我们看一下Base(const string &str)的定义:

Base::Base(const string &str) {
	if(str=="A") p = new A();
	if(str=="B") p = new B();
}
所以当我们调用上述构造函数来创建一个基类对象时,同时将基类的成员指针p指向了一个派生类对象,接下来这个基类对象的所有行为都是派生类的行为,所以基类对象看起来就像一个派生类对象,这就是所谓的“虚构造函数”。下面是完整的代码:

#include<iostream>
#include<string>
using namespace std;

class Base {
	Base *p;
protected:
	Base() { p = NULL; }
public:
	Base(const string &str);
	~Base();
	virtual void func() { p->func(); }
};

class A : public Base {
	A() {}
	A(const A&) {}
	friend class Base;
public:
	void func() { cout<<"This is from A"<<endl; }
};

class B : public Base {
	B() {}
	B(const B&) {}
	friend class Base;
public:
	void func() { cout<<"This is from B"<<endl; }
};

Base::Base(const string &str) {
	if(str=="A") p = new A();
	if(str=="B") p = new B();
}

Base::~Base() {
	delete p;
}

int main() { 
	
	Base *s = new Base("A");
	s->func();
	delete s;

	return 0; 
}
需要注意的是Base中还有一个无参的默认构造函数,这个构造函数将在创建派生类对象的时候被调用,来初始化派生类对象中的基类子对象,即来初始化p,不过这个p对于我们而言是没用的,所以将之初始化为0,不过令p=0还有一个好处,因为在销毁基类对象的时候会调用基类的析构函数,在析构函数中有delete p,这将引发派生类的析构函数,之后派生类的析构函数又会调用基类子对象的析构函数,即会第二次调用基类的析构函数,唯一不同的是此p非彼p,如果此p不为0,可能引发未知的后果。

抽象工厂模式也很简单,其本意是有一大堆派生类工厂,这些派生类工厂根据自己的需要创建合适的对象,直接看代码或许更直观:

class BaseA {};
class A1 : public BaseA{};
class A2 : public BaseA{};

class BaseB {};
class B1 : public BaseB {};
class B2 : public BaseB {};

class Factory {
public:
	virtual BaseA* createA() = 0;
	virtual BaseB* createB() = 0;
};

class OneFactory : public Factory {
	BaseA* createA() { return new A1(); }
	BaseB* createB() { return new B1(); }
};

class TwoFactory : public Factory {
	BaseA* createA() { return new A2(); }
	BaseB* createB() { return new B2(); }
};
Factory提供公共的接口,OneFactory根据自己的需要重新定义createA和createB,生成A1和B1的对象,TwoFactory也是根据自己的需要重新定义createA和createB,来分别生成A2和B2的对象。使用方式如下:

int main() { 
	
	Factory *p1 = new OneFactory();
	p1->createA();
	Factory *p2 = new TwoFactory();
	p2->createA();
	return 0; 
}






  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值