zoukankan      html  css  js  c++  java
  • 【设计模式】原型模式

    /************************************************************************
    设计模式
    原型模式
    
    所谓原型模式,也就是从一个对象再创建另外一个可定制的对象,而且不需要知道
    任何创建的细节。注意的是:必须是同一个类的对象。
    
    从语法角度讲,使用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;
    }

    运行情况如下

  • 相关阅读:
    抛开BlazeDS,自定义flex RPC
    设计模式学习03装饰器模式
    通过ANT生成MANIFEST.MF中的ClassPath属性
    Spring JDBCTemplate与Hiberante混用
    关于 两个 datetime 列的差别导致了运行时溢出
    在Wcf中使用Nhibernate (续)
    sql2005/sql2008 分页
    工行支付api查询asp.net C# 实现
    生成静态页面的vbscript
    Asp.net Mvc Post ID Bug
  • 原文地址:https://www.cnblogs.com/cuish/p/3744836.html
Copyright © 2011-2022 走看看