Behavioral Patterns:
Command
Command
Command Undo
Composite Command
Creational Patterns:
Builder
Fluent Style #1
Fluent Style #2
Groovy Style
Facets
Person.cpp
Person.h
PersonBuilder.cpp
PersonBuilder.h
PersonAddressBuilder.h
PersonJobBuilder.h
Factory
No Factory
Factory #1
Factory #2
Inner Factory
Abstract Factory
Functional Factory
Prototype
Prototype
Singleton
Singleton
Structural Patterns:
Adapter
Adapter
Bridge
Bridge
Pimpl
Person.h
Composite
GraphicObject.cpp
ArrayBackedProps.cpp
Output:
0
deposited 100, balance now 100
withdrew 200, balance now -100
-100
Command:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct BankAccount
{
int balance = 0;
int overdraft_limit = -500;
void deposit(int amount)
{
balance += amount;
cout << “deposited ” << amount << “, balance now ” << balance << “\n”;
}
void withdraw(int amount)
{
if (balance – amount >= overdraft_limit)
{
balance -= amount;
cout << “withdrew ” << amount << “, balance now ” << balance << “\n”;
}
}
};
struct Command
{
virtual ~Command() = default;
virtual void call() const = 0;
virtual void undo() const = 0;
};
struct BankAccountCommand : Command
{
BankAccount& account;
enum Action { deposit, withdraw } action;
int amount;
BankAccountCommand(BankAccount& account, const Action action, const int amount): account(account), action(action), amount(amount)
{
}
void call() const override
{
switch (action)
{
case deposit:
account.deposit(amount);
break;
case withdraw:
account.withdraw(amount);
break;
default: break;
}
}
};
// vector doesn’t have virtual dtor, but who cares?
struct CompositeBankAccountCommand : vector<BankAccountCommand>, Command
{
CompositeBankAccountCommand(const initializer_list<value_type>& items): vector<BankAccountCommand>(items) {}
void call() const override
{
for (auto& cmd : *this)
cmd.call();
}
};
int main()
{
BankAccount ba;
/*vector<BankAccountCommand> commands{*/
CompositeBankAccountCommand commands
{
BankAccountCommand{ ba, BankAccountCommand::deposit, 100 },
BankAccountCommand{ ba, BankAccountCommand::withdraw, 200 }
};
cout << ba.balance << endl;
// apply all the commands
/*for (auto& cmd : commands)
{
cmd.call();
}*/
commands.call();
cout << ba.balance << endl;
getchar();
return 0;
}
Output:
0
deposited 100, balance now 100
withdrew 200, balance now -100
-100
deposited 200, balance now 100
withdrew 100, balance now 0
0
Command Undo:
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <algorithm>
using namespace std;
struct BankAccount
{
int balance = 0;
int overdraft_limit = -500;
void deposit(int amount)
{
balance += amount;
cout << “deposited ” << amount << “, balance now ” << balance << “\n”;
}
bool withdraw(int amount)
{
if (balance – amount >= overdraft_limit)
{
balance -= amount;
cout << “withdrew ” << amount << “, balance now ” << balance << “\n”;
return true;
}
return false;
}
};
struct Command
{
bool succeeded;
virtual void call() = 0;
virtual void undo() = 0;
};
struct BankAccountCommand : Command
{
BankAccount& account;
enum Action { deposit, withdraw } action;
int amount;
BankAccountCommand(BankAccount& account, const Action action, const int amount)
: account(account), action(action), amount(amount)
{
succeeded = false;
}
void call() override
{
switch (action)
{
case deposit:
account.deposit(amount);
succeeded = true;
break;
case withdraw:
succeeded = account.withdraw(amount);
break;
}
}
void undo() override
{
if (!succeeded) return;
switch (action)
{
case withdraw:
if (succeeded)
account.deposit(amount);
break;
case deposit:
account.withdraw(amount);
break;
}
}
};
// vector doesn’t have virtual dtor, but who cares?
struct CompositeBankAccountCommand : vector<BankAccountCommand>, Command
{
CompositeBankAccountCommand(const initializer_list<value_type>& items)
: vector<BankAccountCommand>(items)
{
}
void call() override
{
for (auto& cmd : *this)
cmd.call();
}
void undo() override
{
for (auto it = rbegin(); it != rend(); ++it)
it->undo();
}
};
struct DependentCompositeCommand : CompositeBankAccountCommand
{
explicit DependentCompositeCommand(const initializer_list<value_type>& items)
: CompositeBankAccountCommand{ items }
{
}
void call() override
{
bool ok = true;
for (auto& cmd : *this)
{
if (ok)
{
cmd.call();
ok = cmd.succeeded;
}
else
{
cmd.succeeded = false;
}
}
}
};
struct MoneyTransferCommand : DependentCompositeCommand
{
MoneyTransferCommand(BankAccount& from, BankAccount& to, int amount)
: DependentCompositeCommand{ BankAccountCommand{ from, BankAccountCommand::withdraw, amount },
BankAccountCommand{ to, BankAccountCommand::deposit, amount } }
{
}
};
int main()
{
BankAccount ba;
/*vector<BankAccountCommand> commands{*/
CompositeBankAccountCommand commands{ BankAccountCommand{ ba, BankAccountCommand::deposit, 100 },
BankAccountCommand{ ba, BankAccountCommand::withdraw, 200 } };
cout << ba.balance << endl;
// apply all the commands
/*for (auto& cmd : commands)
{
cmd.call();
}*/
commands.call();
cout << ba.balance << endl;
/*for_each(commands.rbegin(), commands.rend(), [](const BankAccountCommand& cmd) { cmd.undo(); });*/
commands.undo();
cout << ba.balance << endl;
getchar();
return 0;
}
Output:
deposited 100, balance now 100
balance: 100
balance: 0
balance: 100
balance: 0
Composite Command:
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <algorithm>
using namespace std;
struct BankAccount
{
int balance = 0;
int overdraft_limit = -500;
void deposit(int amount)
{
balance += amount;
cout << “deposited ” << amount << “, balance now ” << balance << “\n”;
}
bool withdraw(int amount)
{
if (balance – amount >= overdraft_limit)
{
balance -= amount;
cout << “withdrew ” << amount << “, balance now ” << balance << “\n”;
return true;
}
return false;
}
friend ostream& operator<<(ostream& os, const BankAccount& acct)
{
os << “balance: ” << acct.balance;
return os;
}
};
struct Command
{
bool succeeded;
virtual void call() = 0;
virtual void undo() = 0;
};
struct BankAccountCommand : Command
{
BankAccount& account;
enum Action { deposit, withdraw } action;
int amount;
BankAccountCommand(BankAccount& account, const Action action, const int amount)
: account(account), action(action), amount(amount)
{
succeeded = false;
}
void call() override
{
switch (action)
{
case deposit:
account.deposit(amount);
succeeded = true;
break;
case withdraw:
succeeded = account.withdraw(amount);
break;
}
}
void undo() override
{
if (!succeeded) return;
switch (action)
{
case withdraw:
if (succeeded)
account.deposit(amount);
break;
case deposit:
account.withdraw(amount);
break;
}
}
};
// vector doesn’t have virtual dtor, but who cares?
struct CompositeBankAccountCommand : vector<BankAccountCommand>, Command
{
CompositeBankAccountCommand(const initializer_list<value_type>& items)
: vector<BankAccountCommand>(items)
{
}
void call() override
{
for (auto& cmd : *this)
cmd.call();
}
void undo() override
{
for (auto it = rbegin(); it != rend(); ++it)
it->undo();
}
};
struct DependentCompositeCommand : CompositeBankAccountCommand
{
explicit DependentCompositeCommand(const initializer_list<value_type>& items)
: CompositeBankAccountCommand{ items }
{
}
void call() override
{
bool ok = true;
for (auto& cmd : *this)
{
if (ok)
{
cmd.call();
ok = cmd.succeeded;
}
else
{
cmd.succeeded = false;
}
}
}
};
struct MoneyTransferCommand : DependentCompositeCommand
{
MoneyTransferCommand(BankAccount& from, BankAccount& to, int amount)
: DependentCompositeCommand{ BankAccountCommand{ from, BankAccountCommand::withdraw, amount },
BankAccountCommand{ to, BankAccountCommand::deposit, amount } }
{
}
};
int main()
{
BankAccount ba, ba2;
ba.deposit(100);
MoneyTransferCommand cmd{ ba, ba2, 5000 };
cmd.call();
cout << ba << endl << ba2 << endl;
cmd.undo();
cout << ba << endl << ba2 << endl;
getchar();
return 0;
}
Output:
class Foo
{
}:
class Person
{
string name;
int age;
};
Fluent Style #1:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
struct Field
{
string name, type;
Field(const string& name, const string& type) : name{ name }, type{ type }
{
}
friend ostream& operator<<(ostream& os, const Field& obj)
{
return os << obj.type << ” ” << obj.name << “;”;
}
};
struct Class
{
string name;
vector<Field> fields;
friend ostream& operator<<(ostream& os, const Class& obj)
{
os << “class ” << obj.name << “\n{\n”;
for (auto&& field : obj.fields)
{
os << ” ” << field << “\n”;
}
return os << “};\n”;
}
};
class CodeBuilder
{
Class the_class;
public:
CodeBuilder(const string& class_name)
{
the_class.name = class_name;
}
CodeBuilder& add_field(const string& name, const string& type)
{
the_class.fields.emplace_back(Field{ name, type });
return *this;
}
friend ostream& operator<<(ostream& os, const CodeBuilder& obj)
{
return os << obj.the_class;
}
};
int main()
{
CodeBuilder cb1{ “Foo” };
cout << cb1;
auto cb2 = CodeBuilder{ “Person” }
.add_field(“name”, “string”)
.add_field(“age”, “int”);
cout << cb2;
getchar();
return 0;
}
Output:
<p>hello</p><ul> <li>hello</li> <li>world</li></ul><ul>
<li>
hello
</li>
<li>
world
</li>
</ul>
Fluent Style #2:
#include <string>
#include <vector>
#include <iostream>
namespace html
{
struct Tag
{
std::string name;
std::string text;
std::vector<Tag> children;
std::vector<std::pair<std::string, std::string>> attributes;
friend std::ostream& operator<<(std::ostream& os, const Tag& tag)
{
os << “<” << tag.name;
for (const auto& att : tag.attributes)
os << ” ” << att.first << “=\”” << att.second << “\””;
if (tag.children.size() == 0 && tag.text.length() == 0)
{
os << “/>” << std::endl;
}
else
{
os << “>” << std::endl;
if (tag.text.length())
os << tag.text << std::endl;
for (const auto& child : tag.children)
os << child;
os << “</” << tag.name << “>” << std::endl;
}
return os;
}
protected:
Tag(const std::string& name, const std::string& text) : name{name}, text{text}
{
}
Tag(const std::string& name, const std::vector<Tag>& children) : name{name}, children{children}
{
}
};
struct P : Tag
{
explicit P(const std::string& text) : Tag{“p”, text}
{
}
P(std::initializer_list<Tag> children) : Tag(“p”, children)
{
}
};
struct IMG : Tag
{
explicit IMG(const std::string& url) : Tag{“img”, “”}
{
attributes.emplace_back(make_pair(“src”, url));
}
};
}
int main()
{
using namespace html;
std::cout <<
P
{
IMG {“http://pokemon.com/pikachu.png”}
}
<< std::endl;
getchar();
return 0;
}
Output:
<p>
<img src=”http://pokemon.com/pikachu.png”/>
</p>
Groovy:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <memory>
using namespace std;
struct HtmlBuilder;
struct HtmlElement
{
string name;
string text;
vector<HtmlElement> elements;
const size_t indent_size = 2;
HtmlElement()
{
}
HtmlElement(const string& name, const string& text) : name(name), text(text)
{
}
string str(int indent = 0) const
{
ostringstream oss;
string i(indent_size*indent, ‘ ‘);
oss << i << “<” << name << “>” << endl;
if (text.size() > 0)
oss << string(indent_size*(indent + 1), ‘ ‘) << text << endl;
for (const auto& e : elements)
oss << e.str(indent + 1);
oss << i << “</” << name << “>” << endl;
return oss.str();
}
static unique_ptr<HtmlBuilder> build(string root_name)
{
return make_unique<HtmlBuilder>(root_name);
}
};
struct HtmlBuilder
{
HtmlBuilder(string root_name)
{
root.name = root_name;
}
// void to start with
HtmlBuilder& add_child(string child_name, string child_text)
{
HtmlElement e{ child_name, child_text };
root.elements.emplace_back(e);
return *this;
}
// pointer based
HtmlBuilder* add_child_2(string child_name, string child_text)
{
HtmlElement e{ child_name, child_text };
root.elements.emplace_back(e);
return this;
}
string str() { return root.str(); }
operator HtmlElement() const
{
return root;
}
HtmlElement root;
};
int main()
{
// <p>hello</p>
auto text = “hello”;
string output;
output += “<p>”;
output += text;
output += “</p>”;
printf(“<p>%s</p>”, text);
// <ul><li>hello</li><li>world</li></ul>
string words[] = { “hello”, “world” };
ostringstream oss;
oss << “<ul>”;
for (auto w : words)
oss << ” <li>” << w << “</li>”;
oss << “</ul>”;
printf(oss.str().c_str());
// easier
HtmlBuilder builder{ “ul” };
builder.add_child(“li”, “hello”).add_child(“li”, “world”);
cout << builder.str() << endl;
auto builder2 = HtmlElement::build(“ul”)->add_child_2(“li”, “hello”)->add_child_2(“li”, “world”);
cout << builder2 << endl;
getchar();
return 0;
}
Output:
Person created
Person destroyed
street_address: 123 Londin Road post_code: SW1 1GB city: London company_name: PragmaSoft position: Consultant annual_income: 10000000
Facets:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <string>
using namespace std;
#include “Person.h”
#include “PersonBuilder.h”
#include “PersonAddressBuilder.h”
#include “PersonJobBuilder.h”
int main_()
{
Person p = Person::create()
.lives().at(“123 London Road”).with_postcode(“SW1 1GB”).in(“London”)
.works().at(“PragmaSoft”).as_a(“Consultant”).earning(10e6);
cout << p << endl;
getchar();
return 0;
}
Output:
Person.cpp:
#include “stdafx.h”
#include “Person.h”
#include “PersonBuilder.h”
PersonBuilder Person::create()
{
return PersonBuilder{};
}
Output:
Person.h:
#pragma once
#include “stdafx.h”
#include <string>
#include <iostream>
class PersonBuilder;
class Person
{
// address
std::string street_address, post_code, city;
// employment
std::string company_name, position;
int annual_income = 0;
Person()
{
std::cout << “Person created\n”;
}
public:
~Person()
{
std::cout << “Person destroyed\n”;
}
static PersonBuilder create();
Person(Person&& other)
: street_address{move(other.street_address)},
post_code{move(other.post_code)},
city{move(other.city)},
company_name{move(other.company_name)},
position{move(other.position)},
annual_income{other.annual_income}
{
}
Person& operator=(Person&& other)
{
if (this == &other)
return *this;
street_address = move(other.street_address);
post_code = move(other.post_code);
city = move(other.city);
company_name = move(other.company_name);
position = move(other.position);
annual_income = other.annual_income;
return *this;
}
friend std::ostream& operator<<(std::ostream& os, const Person& obj)
{
return os
<< “street_address: ” << obj.street_address
<< ” post_code: ” << obj.post_code
<< ” city: ” << obj.city
<< ” company_name: ” << obj.company_name
<< ” position: ” << obj.position
<< ” annual_income: ” << obj.annual_income;
}
friend class PersonBuilder;
friend class PersonAddressBuilder;
friend class PersonJobBuilder;
};
Output:
PersonBuilder.cpp:
#include “stdafx.h”
#include “PersonBuilder.h”
#include “PersonAddressBuilder.h”
#include “PersonJobBuilder.h”
PersonAddressBuilder PersonBuilderBase::lives() const
{
return PersonAddressBuilder{ person };
}
PersonJobBuilder PersonBuilderBase::works() const
{
return PersonJobBuilder{ person };
}
Output:
PersonBuilder.h:
#pragma once
#include “stdafx.h”
#include “Person.h”
class PersonAddressBuilder;
class PersonJobBuilder;
class PersonBuilderBase
{
protected:
Person& person;
explicit PersonBuilderBase(Person& person) : person{ person }
{
}
public:
operator Person() const
{
return std::move(person);
}
// builder facets
PersonAddressBuilder lives() const;
PersonJobBuilder works() const;
};
class PersonBuilder : public PersonBuilderBase
{
Person p;
public:
PersonBuilder(): PersonBuilderBase{p}
{
}
};
Output:
PersonAddressBuilder.h:
#pragma once
#include “stdafx.h”
#include <string>
class PersonAddressBuilder : public PersonBuilderBase
{
typedef PersonAddressBuilder Self;
public:
explicit PersonAddressBuilder(Person& person) : PersonBuilderBase{person}
{
}
Self& at(std::string street_address)
{
person.street_address = street_address;
return *this;
}
Self& with_postcode(std::string post_code)
{
person.post_code = post_code;
return *this;
}
Self& in(std::string city)
{
person.city = city;
return *this;
}
};
Output:
PersonJobBuilder.h:
#pragma once
#include “stdafx.h”
#include “PersonBuilder.h”
class PersonJobBuilder : public PersonBuilderBase
{
typedef PersonJobBuilder Self;
public:
explicit PersonJobBuilder(Person& person) : PersonBuilderBase { person }
{
}
Self& at(std::string company_name)
{
person.company_name = company_name;
return *this;
}
Self& as_a(std::string position)
{
person.position = position;
return *this;
}
Self& earning(int annual_income)
{
person.annual_income = annual_income;
return *this;
}
};
Output:
x: 5 y: 6
No Factory:
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
enum class PointType
{
cartesian,
polar
};
struct Point
{
Point(const float a, const float b, PointType type = PointType::cartesian)
{
if (type == PointType::cartesian)
{
x = a;
y = b;
}
else
{
x = a*cos(b);
y = a*sin(b);
}
}
float x, y;
friend std::ostream& operator<<(std::ostream& os, const Point& obj)
{
return os
<< “x: ” << obj.x
<< ” y: ” << obj.y;
}
};
int main()
{
auto p = Point(5, 6, PointType::cartesian);
std::cout << p << std::endl;
getchar();
return 0;
}
Output:
x: 3.53553 y: 3.53553
Factory #1:
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
class Point
{
Point(const float x, const float y) : x{x}, y{y}
{
}
public:
float x, y;
friend std::ostream& operator<<(std::ostream& os, const Point& obj)
{
return os
<< “x: ” << obj.x
<< ” y: ” << obj.y;
}
static Point NewCartesian(float x, float y)
{
return{ x, y };
}
static Point NewPolar(float r, float theta)
{
return{ r*cos(theta), r*sin(theta) };
}
};
int main()
{
auto p = Point::NewPolar(5, M_PI_4);
std::cout << p << std::endl;
return 0;
}
Output:
x: 3.53553 y: 3.53553
Factory #2:
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
class Point
{
public:
Point(float x, float y) : x(x), y(y)
{
}
float x, y;
friend std::ostream& operator<<(std::ostream& os, const Point& obj)
{
return os
<< “x: ” << obj.x
<< ” y: ” << obj.y;
}
};
// separation of concerns
struct PointFactory
{
static Point NewCartesian(float x, float y)
{
return Point{ x, y };
}
static Point NewPolar(float r, float theta)
{
return Point{ r*cos(theta), r*sin(theta) };
}
};
int main()
{
auto p = PointFactory::NewPolar(5, M_PI_4);
std::cout << p << std::endl;
return 0;
}
Output:
x: 2 y: 3
Inner Factory:
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
class Point
{
Point(float x, float y) : x(x), y(y)
{
}
float x, y;
class PointFactory
{
PointFactory()
{
}
static Point NewCartesian(float x, float y)
{
return { x,y };
}
static Point NewPolar(float r, float theta)
{
return{ r*cos(theta), r*sin(theta) };
}
};
public:
static PointFactory Factory;
friend std::ostream& operator<<(std::ostream& os, const Point& obj)
{
return os
<< “x: ” << obj.x
<< ” y: ” << obj.y;
}
};
int main()
{
auto pp = Point::Factory.NewCartesian(2, 3);
std::cout << p << std::endl;
return 0;
}
Output:
Take tea bag, boil water, pour 200ml, add lemon, enjoy
Grind beans, boil water, pour 200ml, add cream, enjoy
Abstract Factory:
#include <iostream>
#include <memory>
#include <map>
using namespace std;
struct HotDrink
{
virtual ~HotDrink() = 0;
virtual void prepare(int volume) = 0;
}
struct Tea : HotDrink
{
void prepare(int volume) override
{
cout << “Take tea bag, boil water, pour ” << volume << “ml, add lemon, enjoy\n”;
}
}
struct Coffee : HotDrink
{
void prepare(int volume) override
{
cout << “Grind beans, boil water, pour ” << volume << “ml, add cream, enjoy\n”;
}
}
struct HotDrinkFactory // abstract factory
{
virtual shared_ptr<HotDrink> make() const = 0;
}
struct TeaFactory : HotDrinkFactory
{
shared_ptr<HotDrink> make() const override
{
return shared_ptr<Tea>();
}
}
struct CoffeeFactory : HotDrinkFactory
{
shared_ptr<HotDrink> make() const override
{
return shared_ptr<Coffee>();
}
}
class DrinkFactory // concrete factory
{
map<string, shared_ptr<HotDrinkFactory>> hot_factories;
public:
DrinkFactory()
{
hot_factories[“coffee”] = make_shared<CoffeeFactory>();
hot_factories[“tea”] = make_shared<TeaFactory>();
}
shared_ptr<HotDrink> make_drink(const string& type)
{
auto drink = hot_factories[type]->make();
drink->prepare(200);
return drink;
}
};
shared_ptr<HotDrink> make_drink(const string& type)
{
shared_ptr<HotDrink> drink;
if (type == “tea”)
{
drink = make_shared<Tea>();
}
else
{
drink = make_shared<Coffee>();
}
drink->prepare(200);
return drink;
}
int main()
{
auto d = make_drink(“tea”);
DrinkFactory df;
df.make_drink(“coffee”);
return 0;
}
Output:
Take tea bag, boil water, pour 200ml, add lemon, enjoy
Functional Factory:
#include <iostream>
#include <memory>
#include <map>
using namespace std;
struct HotDrink
{
virtual ~HotDrink() = default;
virtual void prepare(int volume) = 0;
}
struct Tea : HotDrink
{
void prepare(int volume) override
{
cout << “Take tea bag, boil water, pour ” << volume << “ml, add lemon, enjoy\n”;
}
}
struct Coffee : HotDrink
{
void prepare(int volume) override
{
cout << “Grind beans, boil water, pour ” << volume << “ml, add cream, enjoy\n”;
}
}
class DrinkWithVolumeFactory // functional factory
{
map<string, function<shared_ptr<HotDrink>()>> factories;
public:
DrinkWithVolumeFactory()
{
factories[“tea”] = [] {
auto tea = make_shared<Tea>();
tea->prepare(200);
return tea;
};
}
shared_ptr<HotDrink> make_drink(const string& type)
};
inline shared_ptr<HotDrink> DrinkWithVolumeFactory::make_drink(const string& name)
{
return factories[name]();
}
int main()
{
DrinkWithVolumeFactory df;
df.make_drink(“tea”);
return 0;
}
Output:
true
true
true
true
Prototype:
#include <iostream>
#include <string>
using namespace std;
struct Point
{
int x{ 0 }, y{ 0 };
Point()
{
}
Point(const int x, const int y) : x{ x }, y{ y }
{
}
};
struct Line
{
Point* start, *end;
Line(Point* const start, Point* const end) : start(start), end(end)
{
}
~Line()
{
delete start;
delete end;
}
Line deep_copy() const // basically a copy constructor for itself
{
return Line{ new Point(start->x, start->y), new Point(end->x, end->y) };
}
};
int main()
{
Line line1
{
new Point{ 3, 3 },
new Point{ 10, 10 }
};
auto line2 = line1.deep_copy();
line1.start->x = line1.start->y = line1.end->y = line1.end->y = 0;
if (line1.start->x == 3 != line2.start->x)
cout << “true” << endl;
else
cout << “false” << endl;
if (line1.start->y == 3 != line2.start->y)
cout << “true” << endl;
else
cout << “false” << endl;
if (line1.end->x == 10 != line2.end->x)
cout << “true” << endl;
else
cout << “false” << endl;
if (line1.end->y ==10 != line2.end->y)
cout << “true” << endl;
else
cout << “false” << endl;
return 0;
}
Output:
SingletonClass instance created!
00915CB8
00915CB8
Singleton:
#include <Windows.h>
#include <iostream>
using namespace std;
class SingletonClass
{
public:
static SingletonClass* getInstance()
{
return (!m_instanceSingleton) ? m_instanceSingleton = new SingletonClass : m_instanceSingleton;
}
private:
// private constructor and destructor
SingletonClass() { cout << “SingletonClass instance created!\n”; }
~SingletonClass() {}
// private copy constructor and assignment operator
SingletonClass(const SingletonClass&);
SingletonClass& operator=(const SingletonClass&);
static SingletonClass* m_instanceSingleton;
};
SingletonClass* SingletonClass::m_instanceSingleton = nullptr;
int main()
{
SingletonClass* singleton;
singleton = singleton->getInstance();
cout << singleton << endl;
// Another object gets the reference of the first object!
SingletonClass* anotherSingleton;
anotherSingleton = anotherSingleton->getInstance();
cout << anotherSingleton << endl;
Sleep(5000);
return 0;
}
Output:
LegacyRectangle: create. (120,200) => (180,240)
RectangleAdapter: create. (120,200), width = 60, height = 40
RectangleAdapter: draw.
LegacyRectangle: oldDraw. (120,200) => (180,240)
Adapter:
#include <iostream.h>
typedef int Coordinate;
typedef int Dimension;
// Desired interface
class Rectangle
{
public:
virtual void draw() = 0;
};
// Legacy component
class LegacyRectangle
{
public:
LegacyRectangle(Coordinate x1, Coordinate y1, Coordinate x2, Coordinate y2)
{
x1_ = x1;
y1_ = y1;
x2_ = x2;
y2_ = y2;
cout << “LegacyRectangle: create. (” << x1_ << “,” << y1_ << “) => (“
<< x2_ << “,” << y2_ << “)” << endl;
}
void oldDraw()
{
cout << “LegacyRectangle: oldDraw. (” << x1_ << “,” << y1_ <<
“) => (” << x2_ << “,” << y2_ << “)” << endl;
}
private:
Coordinate x1_;
Coordinate y1_;
Coordinate x2_;
Coordinate y2_;
};
// Adapter wrapper
class RectangleAdapter: public Rectangle, private LegacyRectangle
{
public:
RectangleAdapter(Coordinate x, Coordinate y, Dimension w, Dimension h):
LegacyRectangle(x, y, x + w, y + h)
{
cout << “RectangleAdapter: create. (” << x << “,” << y <<
“), width = ” << w << “, height = ” << h << endl;
}
virtual void draw()
{
cout << “RectangleAdapter: draw.” << endl;
oldDraw();
}
};
int main()
{
Rectangle *r = new RectangleAdapter(120, 200, 60, 40);
r->draw();
}
Output:
Rasterizing a circle of radius 5
Rasterizing a circle of radius 10
Bridge:
#include <string>
#include <vector>
using namespace std;
// two classes of objects
// Renderers – determine how an object is drawn
// Shapes – determine what to draw
struct Renderer
{
virtual void render_circle(float x, float y, float radius) = 0;
};
struct RasterRenderer : Renderer
{
void render_circle(float x, float y, float radius) override
{
cout << “Rasterizing a circle of radius ” << radius << endl;
}
};
struct VectorRenderer : Renderer
{
void render_circle(float x, float y, float radius) override
{
cout << “Drawing a vector circle of radius ” << radius << endl;
}
};
struct Shape
{
protected:
Renderer& renderer;
Shape(Renderer& renderer) : renderer{renderer} {}
public:
virtual void draw() = 0; // implementation specific
virtual void resize(float factor) = 0; // abstraction specific
};
struct Circle : Shape
{
float x, y, radius;
void draw() override
{
renderer.render_circle(x, y, radius);
}
void resize(float factor) override
{
radius *= factor;
}
Circle(Renderer& renderer, float x, float y, float radius) : Shape{renderer},
x{x}, y{y}, radius{radius}
{
}
};
int main()
{
RasterRenderer rr;
Circle raster_circle{ rr, 5,5,5 };
raster_circle.draw();
raster_circle.resize(2);
raster_circle.draw();
getchar();
return 0;
}
Output:
hello my name is: fred
Pimpl:
#include “Person.h”
struct Person::PersonImpl
{
void greet(Person* p);
};
void Person::PersonImpl::greet(Person* p)
{
printf(“hello my name is: %s”, p->_name.c_str());
}
Person::Person() : impl(new PersonImpl)
{
}
Person::~Person()
{
delete impl;
}
void Person::greet()
{
impl->greet(this);
}
int main()
{
// pimpl
// binary interfaces are fragile; this removes most of the internals to a separate class
// prevents recompilation of sources reliant on the header
Person p;
p.greet();
getchar();
return 0;
}
Output:
Person.h:
#pragma once
#include <string>
struct Person
{
std::string name;
class PersonImpl;
PersonImpl* impl; // bridge – not necessarily inner class, can vary
Person(string name);
~Person();
void greet();
};
Output:
Group root contains:
Circle
Group sub contains:
Circle
GraphicObject.cpp:
#pragma once
#include <iostream>
#include <vector>
#include <memory>
struct GraphicObject
{
virtual void draw() = 0;
};
struct Circle : GraphicObject
{
void draw() override
{
std::cout << “Circle” << std::endl;
}
};
struct Group : GraphicObject
{
std::string name;
explicit Group(const std::string& name) : name{name}
{
}
void draw() override
{
std::cout << “Group ” << name.c_str() << ” contains:” << std::endl;
for (auto&& o : objects)
o->draw();
}
std::vector<GraphicObject*> objects;
};
int main()
{
Group root(“root”);
Circle c1, c2;
root.objects.push_back(&c1);
Group subgroup(“sub”);
subgroup.objects.push_back(&c2);
root.objects.push_back(&subgroup);
root.draw();
getchar();
return 0;
}
Output:
The orc has an average stat of 12 and a maximum stat of 16
ArrayBackedProps.cpp: