zoukankan      html  css  js  c++  java
  • 设计模式:原型模式(C++)【克隆羊多莉】

    转载:https://blog.csdn.net/qq_29542611/article/details/79521841

    原型模式介绍

    这节我们继续学习设计模式——原型模式。我们先看看原型模式的标准说法,用原型实例指定创建对象的种类并且通过拷贝这些原型创建新的对象。其实原型模式就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节而已。

    我们先看看C++和其他一些面向对象的编程语言的区别。在java、C# 或者一些其他的面向对象编程语言,他们所有的类都是都会继承或者间接继承Object类。比如说java中Object类 有一个clone方法,实现上就是原型模式的体现,子类需要根据情况进行实现罢了。而我们的C++呢 没有Object(上帝类),所以呢 我们需要在我们自己的原型类中添加一个clone 克隆方法就行了。有人或许会说,C++不是有拷贝构造函数么。确实有默认的拷贝构造函数呀,但是 默认的拷贝构造函数只提供基本的值拷贝,如果有在堆区开辟空间的成员呢?所以我们要提供自己的拷贝构造函数进行深拷贝,方便用户,还应该提供一个clone方法(实际就是去调用拷贝构造函数)。下面看原型模式克隆羊多莉 案例。

    克隆羊多利代码实现

    原型图就是不画了吧,就一个类。。。。对外提供clone方法,如果类成员有在堆区开辟空间,需要重新拷贝构造函数进行深拷贝!clone方法本质还是调用拷贝构造函数。注意,我们的析构函数要释放堆区开辟的内容哟。

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    using namespace std;
     
    class Sheep
    {
        friend ostream& operator<<(ostream&, Sheep& sheep);
    public:
        //构造函数
        Sheep(char* name,int age)
        {
            this->age = age;
            this->name = new char[strlen(name) + 1]{ 0 };
            strcpy(this->name, name);
        }
        //拷贝构造函数
        Sheep(const Sheep& sheep)
        {
            this->age = sheep.age;
            this->name = new char[strlen(sheep.name) + 1]{ 0 };
            strcpy(this->name, sheep.name);
        }
        ~Sheep()
        {
            if (name != NULL)
            {
                delete name;
            }
        }
        //重载 = 赋值运算符
        Sheep& operator=(const Sheep& sheep)
        {
            //1、防止自身赋值
            if (this == &sheep)
            {
                return *this;
            }
            //2、释放原来在堆空间开辟的空间
            if (this->name != NULL)
            {
                delete this->name;
                this->name = NULL;
            }
            //3、执行深拷贝
            this->age = sheep.age;
            this->name = new char[strlen(sheep.name) + 1]{ 0 };
            strcpy(this->name, sheep.name);
        }
        Sheep* clone()
        {
            //直接调用 拷贝构造函数,因为拷贝构造函数已经做了深拷贝的动作。
            return new Sheep(*this);
        }
        
        char* getName()
        {
            return name;
        }
        void setName(char* name)
        {
            if (this->name != NULL)
            {
                delete this->name;
                this->name = NULL;
            }
            this->name = new char[strlen(name) + 1]{ 0 };
            strcpy(this->name, name);
     
        }
        int getAge()
        {
            return age;
        }
        void setAge(int age)
        {
            this->age = age;
        }
    private:
        char* name;
        int age;
    };
    //重载<<运算符
    ostream& operator<<(ostream&, Sheep& sheep)
    {
        cout << "[name = " << sheep.name << " ,age = "<< sheep.age << "]";
        return cout;
    }
     
    int main(int argc, char *argv[])
    {
        Sheep* sheep1 = new Sheep("多利",0);
        Sheep* sheep2 = sheep1->clone();
        cout << "sheep1:" << *sheep1 << endl;
        cout << "sheep2:" << *sheep2 << endl;
        cout << "删除克隆原型sheep1" << endl;
        delete sheep1;
        cout << "sheep2:" << *sheep2 << endl;
     
        return EXIT_SUCCESS;
    }

    运行结果

  • 相关阅读:
    MDX Step by Step 读书笔记(六) Building Complex Sets (复杂集合的处理) Filtering Sets
    在 Visual Studio 2012 开发 SSIS,SSAS,SSRS BI 项目
    微软BI 之SSIS 系列 在 SSIS 中读取 SharePoint List
    MDX Step by Step 读书笔记(五) Working with Expressions (MDX 表达式) Infinite Recursion 和 SOLVE_ORDER 原理解析
    MDX Step by Step 读书笔记(五) Working with Expressions (MDX 表达式)
    使用 SQL Server 2012 Analysis Services Tabular Mode 表格建模 图文教程
    MDX Step by Step 读书笔记(四) Working with Sets (使用集合) Limiting Set and AutoExists
    SQL Server 2012 Analysis Services Tabular Model 读书笔记
    Microsoft SQL Server 2008 MDX Step by Step 学习笔记连载目录
    2011新的开始,介绍一下AgileEAS.NET平台在新的一年中的发展方向
  • 原文地址:https://www.cnblogs.com/Toya/p/14063438.html
Copyright © 2011-2022 走看看