设计模式之虚构造函数模式

1,虚构造函数模式:"现在还不知道需要什么类型的对象,但是有一些信息,请创建适当的对象."
2,实例代码:
#include <iostream>
#include <stdexcept>
#include <vector>
using namespace std;

class Shape
{
    Shape* s;
    Shape(const Shape&);
    Shape operator=(Shape&);
//禁止构造对象
//这里只给派生类动态创建时使用.
protected:
    Shape(){ s=0; }//注:"信封"中s指向实际对象.
    //"信件"中,s只是一个负荷,这里默认构造函数为"信件"将s赋值为0
public:
    virtual void draw(){ s->draw(); };
    virtual ~Shape() //这里将被调用两次
    //第一次派生类s!=0;
    //第二次,基类,此时s==0,delete s无操作.
    {
        cout<<"~Shape"<<endl;
        delete s;//注:delete 0合法,等价于无操作
    }
    class shape_error : public logic_error
    {
    public:
        shape_error(string type):logic_error("Cann't create shape: "+type){}
    };
    Shape(string type) throw(shape_error);
};

class Circle : public Shape
{
    Circle(){}//构造函数设为私有,只创建基类
    Circle(const Circle&);
    Circle operator=(Circle&);
    friend class Shape;
public:
    void draw(){ cout<<"Circle:Draw"<<endl; }
    ~Circle(){ cout<<"Circle:~Circle"<<endl; }
};

class Square : public Shape
{
    Square(){}//构造函数设为私有,只创建基类
    Square(const Square&);
    Square operator=(Square&);
    friend class Shape;
public:
    void draw(){ cout<<"Square:Draw"<<endl; }
    ~Square(){ cout<<"Square:~Square"<<endl; }
};

//核心
Shape::Shape(string type) throw(Shape::shape_error)
{
    if(type=="Circle")
        s=new Circle;
    else if(type=="Square")
        s=new Square;
    else throw shape_error(type);
}

char* sl[] = { "Circle", "Square", "Square", "Circle", "Circle", "Circle", "Square" };
int main()
{
    vector<Shape*> shapes;
    try
    {
        for(size_t i = 0; i < sizeof sl / sizeof sl[0]; i++)
            shapes.push_back(new Shape(sl[i]));//这里虚指针都是指向Shape的一个对象.
    } catch(Shape::shape_error& e)
    {
        cout << e.what() << endl;
        for(vector<Shape*>::iterator ite=shapes.begin();ite!=shapes.end();ite++)
        {
            delete *ite;
        }
        return EXIT_FAILURE;
    }
    for(size_t i = 0; i < shapes.size(); i++)
    {
        shapes[i]->draw();
    }
    //关于析构函数:从Shape的析构函数入口,第一次执行delete s,先派生类析构,然后基类析构,又一次执行delete s
    //此时派生类的s=0,不产生任何操作.
    for(vector<Shape*>::iterator ite=shapes.begin();ite!=shapes.end();ite++)
    {
        delete *ite;
        cout<<endl;
    }
    return 0;
}

你可能感兴趣的:(设计模式)