《C++20设计模式》---原型模式学习笔记代码

C++20设计模式

第 4 章 原型模式

学习笔记

笔记代码

cpp 复制代码
#include<iostream>
#include<string>

// #define VALUE_OF_ADDRESS // PP_4_2_1 (no define: PP_4_2_2)
namespace PP_4_2 {
    class Address
    {
    public:
        std::string street;
        std::string city;
        int suite;
        // Address(std::string& street, std::string& city, int suite)
        //     :street(street), city(city), suite(suite) {
        // }
    };

    class Contact
    {
    public:
        std::string name;
#ifdef VALUE_OF_ADDRESS
        Address address;
#else
        Address* address;
        ~Contact() {
            // 由于存在double free问题, 这块作为测试就不释放内存了
            // delete address;
        }
#endif
    };

    void testOrdinaryCopy() {
#ifdef VALUE_OF_ADDRESS
        // here is the prototype
        Contact worker{"", {"123 East Dr", "London", 0}};

        // make a copy pf prototype and customize it
        Contact john = worker;
        john.name = "John Doe";
        john.address.suite = 10;
#else
        // 下面代码会发生异常,原因是因为存在多次释放Address对象
        // here is the prototype
        Contact worker{"",new Address{"123 East Dr", "London", 0}};
        // make a copy pf prototype and customize it
        Contact john = worker;
        john.name = "John Doe";
        john.address->suite = 10;
#endif
    
    }
} // PP_4_2

namespace PP_4_3 {
    class Address
    {
    public:
        std::string street;
        std::string city;
        int suite;

        Address(){}
        Address(std::string street, std::string city, int suite)
            :street(street), city(city), suite(suite) {
        }
    };

    class Contact
    {
    public:
        std::string name;
        Address *address;

        Contact(){}
        Contact(std::string name, Address *address) : name(name), address(address) {}
        Contact(const Contact& other)
            :name(other.name), address(new Address(*other.address)) { // 这里的会调用Address的默认拷贝构造函数
                // address = new Address{
                // other.address->street,
                // other.address->city,
                // other.address->suite
        }

        Contact operator=(const Contact& other) {
            if (this == &other) {
                return *this;
            }

            name = other.name;
            address = other.address;

            return *this;
        }

        ~Contact() {delete address;}
    };

    void testCopyConstructor() {
        Contact worker{"",new Address{"123 East Dr", "London", 0}};
        // Contact john;
        // john = worker;
        Contact john = worker;
        john.name = "john";
        john.address->suite = 10;
    }
} // PP_4_3

namespace PP_4_4 {
    class Address
    {
    public:
        std::string street;
        std::string city;
        int suite;

        Address(){}
        Address(std::string street, std::string city, int suite)
            :street(street), city(city), suite(suite) {
        }

        virtual Address* clone() {
            return new Address{street, city, suite};
        }
    };

    class ExtendedAddress : public Address {
    public:
        std::string country;
        std::string postcode;

        ExtendedAddress(const std::string& street, const std::string& city, 
            const int suite, const std::string& country,
            const std::string& postcode):Address(street, city, suite), country(country) {
        }

        ExtendedAddress* clone()override {
            return new ExtendedAddress(street, city, suite, country, postcode);
        }
    };

    void testVirtualConstructor() {
        std::cout << __FUNCTION__ <<"() begin.";
        ExtendedAddress ea{"123 East Dr", "London", 0, "UK", "SW101EG"};
        Address& a = ea; //upcast
        auto cloned = a.clone();
        Address xx;

        printf("\nea: %s\n", typeid(ea).name());
        printf("a: %s\n", typeid(a).name());
        printf("cloned: %s\n", typeid(cloned).name());
        printf("cloned: %s\n", typeid(xx).name());

        std::cout << __FUNCTION__ <<"() end.\n\n";
    }
} // PP_4_4

#include<memory>
namespace PP_4_6
{
    class Address
    {
    public:
        std::string street;
        std::string city;
        int suite;

        Address() {}
        Address(std::string street, std::string city, int suite)
            : street(street), city(city), suite(suite)
        {
        }

        virtual Address *clone()
        {
            return new Address{street, city, suite};
        }
    };

    class Contact
    {
    public:
        std::string name;
        Address *address;

        Contact() {}
        Contact(std::string name, Address *address) : name(name), address(address) {}
        Contact(const Contact &other)
            : name(other.name), address(new Address(*other.address))
        {
        }

        Contact operator=(const Contact &other)
        {
            if (this == &other)
            {
                return *this;
            }

            name = other.name;
            address = other.address;

            return *this;
        }

        ~Contact() { delete address; }
    };

    class EmployeeFactory {
        static Contact main;
        static Contact aux;

        static std::unique_ptr<Contact> NewEmployee(std::string name,
            int suite, Contact& proto) {
            auto result = std::make_unique<Contact>(proto); //这里会调用拷贝构造
            result->name = name;
            result->address->suite = suite;
            return result;
        }

    public:
        static std::unique_ptr<Contact> NewMainOfficeEmployee(
            std::string name , int suite) {
            return NewEmployee(name, suite, main);
        }

        static std::unique_ptr<Contact> NewAuxMainOfficeEmployee(
            std::string name, int suite) {
            return NewEmployee(name, suite, aux);
        }
    };

    Contact EmployeeFactory::main{"", new Address{"123 East Dr", "London", 0}};
    Contact EmployeeFactory::aux{"", new Address{"123B East Dr", "London", 0}};

    void testPrototypeFactory() {
        auto john = EmployeeFactory::NewMainOfficeEmployee("John Doe", 123);
        auto jane = EmployeeFactory::NewAuxMainOfficeEmployee("Jane Doe", 125);
    }

} // PP_4_6

int main()
{
    PP_4_2::testOrdinaryCopy();
    PP_4_3::testCopyConstructor();
    PP_4_4::testVirtualConstructor();
    PP_4_6::testPrototypeFactory();
    return 0;
}
相关推荐
叶甯14 分钟前
【设计模式】单例模式
设计模式
诺亚凹凸曼4 小时前
23种设计模式-行为型模式-模板方法
设计模式
云徒川5 小时前
【设计模式】责任链模式
设计模式·责任链模式
振鹏Dong6 小时前
剖析Spring中的设计模式(一) | 工厂&观察者
java·spring·设计模式
user_agent6 小时前
MCP 了解一下
前端·设计模式
Koma-forever6 小时前
java设计模式-代理模式
java·设计模式·模板方法模式
hycccccch8 小时前
设计模式(23种设计模式简介)
设计模式
小胖子许愿17 小时前
设计模式 - 代理模式
设计模式·代理模式
Sitarrrr1 天前
【WPF】IOC控制反转的应用:弹窗但不互相调用ViewModel
设计模式·c#·wpf
蓝天居士1 天前
软考 系统架构设计师系列知识点 —— 设计模式之抽象工厂模式
设计模式·系统架构·抽象工厂模式