ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

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

2026/9/14 6:57:43 拓冰建站 浏览量
《C++20设计模式》---原型模式学习笔记代码

C++20设计模式

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

第 4 章 原型模式

学习笔记

笔记代码


#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_ADDRESSAddress address;
#elseAddress* address;~Contact() {// 由于存在double free问题, 这块作为测试就不释放内存了// delete address;}
#endif};void testOrdinaryCopy() {
#ifdef VALUE_OF_ADDRESS// here is the prototypeContact worker{"", {"123 East Dr", "London", 0}};// make a copy pf prototype and customize itContact john = worker;john.name = "John Doe";john.address.suite = 10;
#else// 下面代码会发生异常,原因是因为存在多次释放Address对象// here is the prototypeContact worker{"",new Address{"123 East Dr", "London", 0}};// make a copy pf prototype and customize itContact john = worker;john.name = "John Doe";john.address->suite = 10;
#endif}
} // PP_4_2namespace 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_3namespace 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; //upcastauto 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_6int main()
{PP_4_2::testOrdinaryCopy();PP_4_3::testCopyConstructor();PP_4_4::testVirtualConstructor();PP_4_6::testPrototypeFactory();return 0;
}