Prototype_Pattern_2 - 8BitsCoding/RobotMentor GitHub Wiki
struct Address
{
string street;
string city;
int suite;
};
struct Contact
{
string name;
Address* address;
};
int main()
{
Contact john = {"john doe", Address{{"123 East Dr"},{"London"},123}};
Contact jane = {"jane smith", Address{{"123 East Dr"},{"London"},103}};
}매번 멤버가 추가될때 저런식으로 한줄씩 너어야 할까?
Contact john = {"john doe", Address{{"123 East Dr"},{"London"},123}};
Contact jane = john;
jane.name = "jane smith";
jane->address.suite = 123;위 방식의 문제는 누군가 이렇게 쓸때 이다.
Contact john = {"john doe", new Address{{"123 East Dr"},{"London"},123}};
Contact jane = john;
jane.name = "jane smith";
jane.address->suite = 123;돌려보면 알겠지만 john과 jane이 같은 방에 살게된다.
위 문제를 Copy contructor를 생성해서 막아보자.
// struct Contact
Contact(const Contact& other)
: name {other.name}
, address {new Address{other.address->street, other.address->city, other.address->suite}}
{
}
// main
Contact john = {"john doe", new Address{{"123 East Dr"},{"London"},123}};
Contact jane{john};
jane.name = "jane smith";
jane.address->suite = 123;같은 방에 사는 문제가 해결된다.
Address도 좀 더 최적화 할 수 있을거 같은데?
// struct Address
Address(const Address& address)
: street{address.street}, city{address.city}, suite{address.suite}
{
}
// struct Contact
Contact(const Contact& other)
: name {other.name}
, address {new Address{*other.address}}
{
}
// main
Contact john = {"john doe", new Address{{"123 East Dr"},{"London"},123}};
Contact jane{john};
jane.name = "jane smith";
jane.address->suite = 123;Factory를 통해서 좀 더 쉽게 만들어 보자.
struct EmployeeFactory
{
static unique_ptr<Contack> new_main_office_employee(const string& name, const int suite)
{
static Contact p{"", new Address{"123 East Dr", "London", 0}};
return new_employee(name, suite, p);
}
private:
static unique_ptr<Contact> new_employee(const string& name, int suite, const Contact& prototype)
{
auto result = make_unique<Contact>(prototype);
result->name = name;
result->address->suite = suite;
return result;
}
}
int main()
{
auto john = EmployeeFactory::new_main_office_employee("Jogn", 123);
}내가 Serialization을 쓰지 않아서 정리하지 않음
boost의 serialization과 관련된 내용
#include <string>
#include <iostream>
#include <memory>
#include <functional>
#include <sstream>
#include "Person.h"
using namespace std;
#include <boost/serialization/serialization.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
struct Address
{
string street;
string city;
int suite;
Address(const string& street, const string& city, const int suite)
: street{street},
city{city},
suite{suite}
{
}
/*Address(const Address& other)
: street{other.street},
city{other.city},
suite{other.suite}
{
}*/
friend ostream& operator<<(ostream& os, const Address& obj)
{
return os
<< "street: " << obj.street
<< " city: " << obj.city
<< " suite: " << obj.suite;
}
};
struct Contact
{
string name;
Address* address;
Contact& operator=(const Contact& other)
{
if (this == &other)
return *this;
name = other.name;
address = other.address;
return *this;
}
Contact() : name(nullptr), address(nullptr)
{} // required for serialization
Contact(string name, Address* address)
: name{name}, address{address}
{
//this->address = new Address{ *address };
}
Contact(const Contact& other)
: name{other.name}
//, address{ new Address{*other.address} }
{
address = new Address(
other.address->street,
other.address->city,
other.address->suite
);
}
private:
friend class boost::serialization::access;
template <class archive>
void save(archive& ar, const unsigned version) const
{
ar << name;
ar << address;
}
template <class archive>
void load(archive& ar, const unsigned version)
{
ar >> name;
ar >> address;
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
public:
~Contact()
{
delete address;
}
friend ostream& operator<<(ostream& os, const Contact& obj)
{
return os
<< "name: " << obj.name
<< " works at " << *obj.address; // note the star here
}
};
struct EmployeeFactory
{
static Contact main;
static Contact aux;
static unique_ptr<Contact> NewMainOfficeEmployee(string name, int suite)
{
//static Contact p{ "", new Address{ "123 East Dr", "London", 0 } };
return NewEmployee(name, suite, main);
}
static unique_ptr<Contact> NewAuxOfficeEmployee(string name, int suite)
{
return NewEmployee(name, suite, aux);
}
private:
static unique_ptr<Contact> NewEmployee(string name, int suite, Contact& proto)
{
auto result = make_unique<Contact>(proto);
result->name = name;
result->address->suite = suite;
return result;
}
};
//Contact EmployeeFactory::main{ "", new Address{ "123 East Dr", "London", 0 } };
//Contact EmployeeFactory::aux{ "", new Address{ "123B East Dr", "London", 0 } };
int main_3423()
{
// this is tedious
// Contact john{ "John Doe", new Address{"123 East Dr", "London"} };
// Contact jane{ "Jane Doe", new Address{"123 East Dr", "London"} };
auto addr = new Address{ "123 East Dr", "London", 0 /* ? */ };
//Contact john{ "John Doe", addr };
//john.address->suite = 123;
//Contact jane{ "Jane Doe", addr };
//jane.address->suite = 124;
//Contact jane2{ jane }; // shallow copy
//jane2.address->suite = 555;
//
//std::cout << jane2 << std::endl;
// whenever an address is needed, make a copy
/*Contact john{ "John Doe", new Address{*addr} };
john.address->suite = 123;
Contact jane{ "Jane Doe", new Address{*addr} };
jane.address->suite = 125;
cout << john << "\n" << jane << endl;*/
// much better. let's list employees
//Contact employee{ "Unknown", new Address{"628 Happy St", "Joy", 0} };
//// we can use this prototype to create john and jane
//Contact john{ employee };
//john.name = "John Doe";
//john.address->suite = 123;
//Contact jane{ employee };
//jane.name = "Jane Doe";
//jane.address->suite = 125;
//cout << john << "\n" << jane << "\n";
//delete addr;
// 4. Boost Serialization
// too much work in getting the copying working
//auto john = EmployeeFactory::NewAuxOfficeEmployee("John Doe", 123);
//auto jane = EmployeeFactory::NewMainOfficeEmployee("Jane Doe", 125);
//cout << *john << "\n" << *jane << "\n"; // note the stars here
delete addr;
getchar();
return 0;
}