/*
(c) 2012 +++ Filip Stoklas, aka FipS, http://www.4FipS.com +++
THIS CODE IS FREE - LICENSED UNDER THE MIT LICENSE
ARTICLE URL: http://forums.4fips.com/viewtopic.php?f=3&t=725
*/
#include <string>
#include <algorithm>
#include <cassert>
#include <iostream>
class Person
{
public:
Person(const std::string &first_name, const std::string &last_name, int age):
_first_name(first_name), _last_name(last_name), _age(age)
{
// in general here might come quite a complex initialization, it would
// be error prone to duplicate the logic in setters() and resetters()
assert(!_first_name.empty() && !_last_name.empty());
_initials = std::string(1, _first_name[0]) + std::string(1, _last_name[0]);
assert(!std::any_of(_initials.begin(), _initials.end(), ::islower));
_full_info = _first_name + " " + _last_name + ", aka " + _initials;
}
// just keep swap() in sync with the constructors and 'operator =', that's all!
void swap(Person &other)
{
std::swap(_first_name, other._first_name);
std::swap(_last_name, other._last_name);
std::swap(_age, other._age);
std::swap(_initials, other._initials);
std::swap(_full_info, other._full_info);
}
// just a bunch of getters, there's no need for setters() nor resetters() !!!
const std::string & first_name() const { return _first_name; }
const std::string & last_name() const { return _last_name; }
int age() const { return _age; }
// more getters...
const std::string & full_info() { return _full_info; }
private:
std::string _first_name;
std::string _last_name;
int _age;
// in general here come various derived or cached data...
std::string _initials;
std::string _full_info;
};
int main()
{
Person p("Jonh", "Doe", 25);
std::cout << p.full_info() << " (at " << &p << ")\n";
// here comes the magic, set the last name by swapping the whole object
Person(p.first_name(), "Foo", p.age()).swap(p);
std::cout << p.full_info() << " (at " << &p << ")\n";
// a full reset is also trivial, note that all the swaps() preserve
// object's identity (address)
Person("Jane", "Roe", 18).swap(p);
std::cout << p.full_info() << " (at " << &p << ")\n";
return 0;
}
// output:
// Jonh Doe, aka JD (at 002BF820)
// Jonh Foo, aka JF (at 002BF820)
// Jane Roe, aka JR (at 002BF820)