第 4 章 原型模式
学习笔记
笔记代码
#include
#include
namespace PP_4_2 {
class Address
{
public:
std::string street;
std::string city;
int suite;
};
class Contact
{
public:
std::string name;
#ifdef VALUE_OF_ADDRESS
Address address;
#else
Address* address;
~Contact() {
}
#endif
};
void testOrdinaryCopy() {
#ifdef VALUE_OF_ADDRESS
Contact worker{"", {"123 East Dr", "London", 0}};
Contact john = worker;
john.name = "John Doe";
john.address.suite = 10;
#else
Contact 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
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;
}