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;
    }

    运行情况如下

  • 相关阅读:
    JS BOM对象 History对象 Location对象
    JS 字符串对象 数组对象 函数对象 函数作用域
    JS 引入方式 基本数据类型 运算符 控制语句 循环 异常
    Pycharm Html CSS JS 快捷方式创建元素
    CSS 内外边距 float positio属性
    CSS 颜色 字体 背景 文本 边框 列表 display属性
    【Android】RxJava的使用(三)转换——map、flatMap
    【Android】RxJava的使用(二)Action
    【Android】RxJava的使用(一)基本用法
    【Android】Retrofit 2.0 的使用
  • 原文地址:https://www.cnblogs.com/cuish/p/3744836.html
Copyright © 2011-2022 走看看