【设计模式】原型模式

/************************************************************************
设计模式
原型模式

所谓原型模式,也就是从一个对象再创建另外一个可定制的对象,而且不需要知道
任何创建的细节。注意的是:必须是同一个类的对象。

从语法角度讲,使用C++来实现原型模式,关键的是【拷贝构造函数】。
在main函数中,有两种写法,第一种是有点问题的:没有使用抽象基类来操作,
第二种是修正了的,使用了抽象基类来操作。

************************************************************************/

 

【天才】类,抽象基类 ,Clone克隆接口,留给子类实现

//【天才】类
class CGenius
{
public:
    CGenius(string strName, int age);
    CGenius();
    virtual ~CGenius();
    virtual void Set(string strName, int age) ;
    virtual CGenius* Clone() = 0;
    virtual void Show() const;

protected:
    string m_strName;
    int    m_nAge;
};

CGenius::CGenius(string strName, int age) : m_strName(strName), m_nAge(age){}
CGenius::CGenius(){}
CGenius::~CGenius(){} 


void CGenius::Set(string strName, int age)
{
    this->m_strName = strName;
    this->m_nAge = age;
}

void CGenius::Show() const
{
    cout << "name is "<<m_strName<<", age is "<<m_nAge<<endl;
}

 

 

【爱因斯坦】类,实现了Clone接口,关键用到了拷贝构造函数,需要注意:在写代码过程报了一个错:那就是当为【爱因斯坦】类写了拷贝构造函数时,必须为其父类【天才】类写一个默认的构造函数,否则报错。

//【爱因斯坦】类
class Einstein : public CGenius
{
public:
    Einstein(string strName, int age);
    Einstein(const Einstein& einstein);  //拷贝构造函数
    virtual ~Einstein();
    virtual void Set(string strName, int age);
    virtual CGenius* Clone();
    virtual void Show() const;
};

Einstein::Einstein(string strName, int age) : CGenius(strName, age){}

Einstein::Einstein(const Einstein& einstein)
{
    this->m_strName = einstein.m_strName;
    this->m_nAge = einstein.m_nAge;
}

Einstein::
~Einstein(){} //调用基类函数 void Einstein::Set(string strName, int age) { CGenius::Set(strName, age); } CGenius* Einstein::Clone() { //调用其拷贝构造函数 return new Einstein(*this); } //调用基类函数 void Einstein::Show() const { CGenius::Show(); }

 

 

 

main函数,在客户端中使用这个模式时,犯了点小二,不过改正了,详见代码和代码注释

int _tmain(int argc, _TCHAR* argv[])
{
    //////////////////开始 有点瑕疵的代码///////////////////////////////////////

    //期望输出 Einstein, 50
    Einstein *pEinstein = new Einstein("Einstein", 50);
    pEinstein->Show();

    cout<<endl<<"--------------------------------"<<endl;
 

    //下面这行代码就是有瑕疵的地方,这段代码正常运行
    //但是却使用了一个dynamic_case转换
    //如果把用到的Einstein类名都改为抽象基类CGenius
    //完全可以不实用dynamic_case
    //详见下面另一段代码

    //从pEinstein克隆而来,期望的输出是Einstein, 50
    Einstein *pEinstein2 = dynamic_cast<Einstein*>(pEinstein->Clone());
    pEinstein2->Show();

    cout<<endl<<"--------------------------------"<<endl;

    //重新设置一下pEinstein2的值,期望输出zhangsan, 51
    pEinstein2->Set("zhangsan", 51);
    pEinstein2->Show();

    cout<<endl<<"--------------------------------"<<endl;

    //重新输入pEinstein的值,期望输出Einstein, 50
    pEinstein->Show();

    delete pEinstein; pEinstein = NULL;
    delete pEinstein2; pEinstein2 = NULL;

    //////////////////结束 有点瑕疵的代码///////////////////////////////////////
    //使用抽象基类指针,多态来使用原型模式

    cout<<endl<<"--------------------------------"<<endl;
    cout<<endl<<"----------华丽的分割线----------------------"<<endl;
    cout<<endl<<"--------------------------------"<<endl;



    //////////////////开始  修正后的代码///////////////////////////////////////
    //期望输出 爱因斯坦, 50
    CGenius* pGenius = new Einstein("爱因斯坦", 50);
    pGenius->Show();

    cout<<endl<<"--------------------------------"<<endl;

    //从pGenius克隆而来,期望输出 爱因斯坦, 50
    CGenius* pGenius2 = pGenius->Clone();
    pGenius2->Show();

    cout<<endl<<"--------------------------------"<<endl;

    //改变pGenius2的值,期望输出 张三,51
    pGenius2->Set("张三", 51);
    pGenius2->Show();

    cout<<endl<<"--------------------------------"<<endl;

    //重新输出pGenius的值,期望输出 爱因斯坦, 50
    pGenius->Show();

    delete pGenius; pGenius = NULL;
    delete pGenius2; pGenius2 = NULL;

    //////////////////结束  修正后的代码///////////////////////////////////////


    cout<<endl<<endl;
    return 0;
}

 

 

 

运行情况如下

 

 

 

 

posted on 2014-05-22 01:17  崔好好  阅读(298)  评论(0编辑  收藏  举报

导航