您的位置:首页 > 其它

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

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

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐