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

C++20设计模式

  • 第 4 章 原型模式
    • 学习笔记
    • 笔记代码

第 4 章 原型模式

学习笔记

笔记代码


#include
#include

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

你可能感兴趣的:(设计模式,c++20,设计模式,原型模式)