第 4 章 原型模式
笔记代码
#include<iostream>
#include<string>
namespace PP_4_2 {class Address{public:std::string street;std::string city;int suite;};class Contact{public:std::string name;
#ifdef VALUE_OF_ADDRESSAddress address;
#elseAddress* address;~Contact() {}
#endif};void testOrdinaryCopy() {
#ifdef VALUE_OF_ADDRESSContact worker{"", {"123 East Dr", "London", 0}};Contact john = worker;john.name = "John Doe";john.address.suite = 10;
#elseContact worker{"",new Address{"123 East Dr", "London", 0}};Contact john = worker;john.name = "John Doe";john.address->suite = 10;
#endif}
} 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)) { }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 = worker;john.name = "john";john.address->suite = 10;}
} 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; 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";}
} #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);}} int main()
{PP_4_2::testOrdinaryCopy();PP_4_3::testCopyConstructor();PP_4_4::testVirtualConstructor();PP_4_6::testPrototypeFactory();return 0;
}