code refactoring: fix memory leaks, code style, etc.

This commit is contained in:
Jakub Vojvoda
2019-01-31 19:57:40 +01:00
parent a8681552c4
commit a0b0ea4f8e
24 changed files with 960 additions and 566 deletions

View File

@@ -5,7 +5,7 @@
*
* Source code is licensed under MIT License
* (for more details see LICENSE)
*
*
*/
#include <iostream>
@@ -15,9 +15,12 @@
* products implement the same interface so that the classes can refer
* to the interface not the concrete product
*/
class ProductA {
class ProductA
{
public:
virtual std::string getName() = 0;
virtual ~ProductA() {}
virtual const char* getName() = 0;
// ...
};
@@ -25,16 +28,25 @@ public:
* ConcreteProductAX and ConcreteProductAY
* define objects to be created by concrete factory
*/
class ConcreteProductAX : public ProductA {
class ConcreteProductAX : public ProductA
{
public:
std::string getName() {
~ConcreteProductAX() {}
const char* getName()
{
return "A-X";
}
// ...
};
class ConcreteProductAY : public ProductA {
std::string getName() {
class ConcreteProductAY : public ProductA
{
public:
~ConcreteProductAY() {}
const char* getName()
{
return "A-Y";
}
// ...
@@ -45,9 +57,12 @@ class ConcreteProductAY : public ProductA {
* same as Product A, Product B declares interface for concrete products
* where each can produce an entire set of products
*/
class ProductB {
class ProductB
{
public:
virtual std::string getName() = 0;
virtual ~ProductB() {}
virtual const char* getName() = 0;
// ...
};
@@ -55,15 +70,25 @@ public:
* ConcreteProductBX and ConcreteProductBY
* same as previous concrete product classes
*/
class ConcreteProductBX : public ProductB {
std::string getName() {
class ConcreteProductBX : public ProductB
{
public:
~ConcreteProductBX() {}
const char* getName()
{
return "B-X";
}
// ...
};
class ConcreteProductBY : public ProductB {
std::string getName() {
class ConcreteProductBY : public ProductB
{
public:
~ConcreteProductBY() {}
const char* getName()
{
return "B-Y";
}
// ...
@@ -73,8 +98,11 @@ class ConcreteProductBY : public ProductB {
* Abstract Factory
* provides an abstract interface for creating a family of products
*/
class AbstractFactory {
class AbstractFactory
{
public:
virtual ~AbstractFactory() {}
virtual ProductA *createProductA() = 0;
virtual ProductB *createProductB() = 0;
};
@@ -84,23 +112,33 @@ public:
* each concrete factory create a family of products and client uses
* one of these factories so it never has to instantiate a product object
*/
class ConcreteFactoryX : public AbstractFactory {
class ConcreteFactoryX : public AbstractFactory
{
public:
ProductA *createProductA() {
~ConcreteFactoryX() {}
ProductA *createProductA()
{
return new ConcreteProductAX();
}
ProductB *createProductB() {
ProductB *createProductB()
{
return new ConcreteProductBX();
}
// ...
};
class ConcreteFactoryY : public AbstractFactory {
class ConcreteFactoryY : public AbstractFactory
{
public:
ProductA *createProductA() {
~ConcreteFactoryY() {}
ProductA *createProductA()
{
return new ConcreteProductAY();
}
ProductB *createProductB() {
ProductB *createProductB()
{
return new ConcreteProductBY();
}
// ...
@@ -109,14 +147,20 @@ public:
int main()
{
ConcreteFactoryX *factoryX = new ConcreteFactoryX();
ConcreteFactoryY *factoryY = new ConcreteFactoryY();
ConcreteFactoryX *factoryX = new ConcreteFactoryX();
ConcreteFactoryY *factoryY = new ConcreteFactoryY();
ProductA *p1 = factoryX->createProductA();
std::cout << "Product: " << p1->getName() << std::endl;
ProductA *p2 = factoryY->createProductA();
std::cout << "Product: " << p2->getName() << std::endl;
return 0;
ProductA *p1 = factoryX->createProductA();
std::cout << "Product: " << p1->getName() << std::endl;
ProductA *p2 = factoryY->createProductA();
std::cout << "Product: " << p2->getName() << std::endl;
delete p1;
delete p2;
delete factoryX;
delete factoryY;
return 0;
}

View File

@@ -14,8 +14,11 @@
* Target
* defines specific interface that Client uses
*/
class Target {
class Target
{
public:
virtual ~Target() {}
virtual void request() = 0;
// ...
};
@@ -25,11 +28,14 @@ public:
* all requests get delegated to the Adaptee which defines
* an existing interface that needs adapting
*/
class Adaptee {
class Adaptee
{
public:
void specificRequest() {
~Adaptee() {}
void specificRequest()
{
std::cout << "specific request" << std::endl;
// ...
}
// ...
};
@@ -40,11 +46,12 @@ public:
* to request on a Target by extending both classes
* ie adapts the interface of Adaptee to the Target interface
*/
class Adapter : public Target, private Adaptee {
class Adapter : public Target, private Adaptee
{
public:
virtual void request() {
virtual void request()
{
specificRequest();
// ...
}
// ...
};
@@ -54,6 +61,7 @@ int main()
{
Target *t = new Adapter();
t->request();
delete t;
return 0;
}

View File

@@ -14,8 +14,11 @@
* Target
* defines specific interface that Client uses
*/
class Target {
class Target
{
public:
virtual ~Target() {}
virtual void request() = 0;
// ...
};
@@ -26,11 +29,12 @@ public:
* to Adapter it will get calls that client makes on the Target
*
*/
class Adaptee {
class Adaptee
{
public:
void specificRequest() {
void specificRequest()
{
std::cout << "specific request" << std::endl;
// ...
}
// ...
};
@@ -40,17 +44,20 @@ public:
* implements the Target interface and when it gets a method call it
* delegates the call to a Adaptee
*/
class Adapter : public Target {
class Adapter : public Target
{
public:
Adapter() : adaptee() {}
~Adapter() {
~Adapter()
{
delete adaptee;
}
void request() {
void request()
{
adaptee->specificRequest();
// ...
// ...
}
// ...
@@ -64,6 +71,7 @@ int main()
{
Target *t = new Adapter();
t->request();
delete t;
return 0;
}

View File

@@ -14,8 +14,11 @@
* Implementor
* defines the interface for implementation classes
*/
class Implementor {
class Implementor
{
public:
virtual ~Implementor() {}
virtual void action() = 0;
// ...
};
@@ -24,17 +27,25 @@ public:
* Concrete Implementors
* implement the Implementor interface and define concrete implementations
*/
class ConcreteImplementorA : public Implementor {
class ConcreteImplementorA : public Implementor
{
public:
void action() {
~ConcreteImplementorA() {}
void action()
{
std::cout << "Concrete Implementor A" << std::endl;
}
// ...
};
class ConcreteImplementorB : public Implementor {
class ConcreteImplementorB : public Implementor
{
public:
void action() {
~ConcreteImplementorB() {}
void action()
{
std::cout << "Concrete Implementor B" << std::endl;
}
// ...
@@ -44,8 +55,11 @@ public:
* Abstraction
* defines the abstraction's interface
*/
class Abstraction {
class Abstraction
{
public:
virtual ~Abstraction() {}
virtual void operation() = 0;
// ...
};
@@ -54,16 +68,19 @@ public:
* RefinedAbstraction
* extends the interface defined by Abstraction
*/
class RefinedAbstraction : public Abstraction {
class RefinedAbstraction : public Abstraction
{
public:
RefinedAbstraction(Implementor *impl)
: implementor(impl) {}
void operation() {
~RefinedAbstraction() {}
RefinedAbstraction(Implementor *impl) : implementor(impl) {}
void operation()
{
implementor->action();
}
// ...
private:
Implementor *implementor;
};
@@ -73,12 +90,18 @@ int main()
{
Implementor *ia = new ConcreteImplementorA;
Implementor *ib = new ConcreteImplementorB;
Abstraction *abstract1 = new RefinedAbstraction(ia);
abstract1->operation();
Abstraction *abstract2 = new RefinedAbstraction(ib);
abstract2->operation();
delete abstract1;
delete abstract2;
delete ia;
delete ib;
return 0;
}

View File

@@ -14,18 +14,23 @@
* Product
* the final object that will be created using Builder
*/
class Product {
class Product
{
public:
void makeA(const std::string &part) {
void makeA( const std::string &part )
{
partA = part;
}
void makeB(const std::string &part) {
void makeB( const std::string &part )
{
partB = part;
}
void makeC(const std::string &part) {
void makeC( const std::string &part )
{
partC = part;
}
std::string get() {
std::string get()
{
return (partA + " " + partB + " " + partC);
}
// ...
@@ -41,21 +46,21 @@ private:
* Builder
* abstract interface for creating products
*/
class Builder {
class Builder
{
public:
virtual ~Builder() {
// ...
}
Product get() {
virtual ~Builder() {}
Product get()
{
return product;
}
virtual void buildPartA() = 0;
virtual void buildPartB() = 0;
virtual void buildPartC() = 0;
// ...
protected:
Product product;
};
@@ -64,30 +69,38 @@ protected:
* Concrete Builder X and Y
* create real products and stores them in the composite structure
*/
class ConcreteBuilderX : public Builder {
class ConcreteBuilderX : public Builder
{
public:
void buildPartA() {
product.makeA("A-X");
void buildPartA()
{
product.makeA( "A-X" );
}
void buildPartB() {
product.makeB("B-X");
void buildPartB()
{
product.makeB( "B-X" );
}
void buildPartC() {
product.makeC("C-X");
void buildPartC()
{
product.makeC( "C-X" );
}
// ...
};
class ConcreteBuilderY : public Builder {
class ConcreteBuilderY : public Builder
{
public:
void buildPartA() {
product.makeA("A-Y");
void buildPartA()
{
product.makeA( "A-Y" );
}
void buildPartB() {
product.makeB("B-Y");
void buildPartB()
{
product.makeB( "B-Y" );
}
void buildPartC() {
product.makeC("C-Y");
void buildPartC()
{
product.makeC( "C-Y" );
}
// ...
};
@@ -98,26 +111,32 @@ public:
*/
class Director {
public:
Director() : builder(nullptr) {}
~Director() {
if (builder) {
Director() : builder() {}
~Director()
{
if ( builder )
{
delete builder;
}
}
void set(Builder *b) {
if (builder) {
void set( Builder *b )
{
if ( builder )
{
delete builder;
}
builder = b;
}
Product get() {
Product get()
{
return builder->get();
}
void construct() {
void construct()
{
builder->buildPartA();
builder->buildPartB();
builder->buildPartC();
@@ -133,17 +152,17 @@ private:
int main()
{
Director director;
director.set(new ConcreteBuilderX);
director.set( new ConcreteBuilderX );
director.construct();
Product product1 = director.get();
std::cout << "1st product parts: " << product1.get() << std::endl;
director.set(new ConcreteBuilderY);
director.set( new ConcreteBuilderY );
director.construct();
Product product2 = director.get();
std::cout << "2nd product parts: " << product2.get() << std::endl;
return 0;
}

View File

@@ -1,5 +1,5 @@
/*
* C++ Design Patterns: Commnand
* C++ Design Patterns: Command
* Author: Jakub Vojvoda [github.com/JakubVojvoda]
* 2016
*
@@ -12,12 +12,14 @@
/*
* Receiver
* knows how to perform the operations associated
* knows how to perform the operations associated
* with carrying out a request
*/
class Receiver {
class Receiver
{
public:
void action() {
void action()
{
std::cout << "Receiver: execute action" << std::endl;
}
// ...
@@ -27,33 +29,37 @@ public:
* Command
* declares an interface for all commands
*/
class Command {
class Command
{
public:
virtual ~Command() {}
virtual void execute() = 0;
// ...
protected:
Command() {}
};
/*
* Concrete Command
* implements execute by invoking the corresponding
* operation(s) on Receiver
* implements execute by invoking the corresponding
* operation(s) on Receiver
*/
class ConcreteCommand : public Command {
class ConcreteCommand : public Command
{
public:
ConcreteCommand(Receiver *r)
: receiver(r) {}
~ConcreteCommand() {
if (receiver) {
ConcreteCommand( Receiver *r ) : receiver( r ) {}
~ConcreteCommand()
{
if ( receiver )
{
delete receiver;
}
}
void execute() {
void execute()
{
receiver->action();
}
// ...
@@ -67,15 +73,19 @@ private:
* Invoker
* asks the command to carry out the request
*/
class Invoker {
class Invoker
{
public:
void set(Command *c) {
void set( Command *c )
{
command = c;
}
void confirm() {
if (command) {
command->execute();
void confirm()
{
if ( command )
{
command->execute();
}
}
// ...
@@ -88,12 +98,11 @@ private:
int main()
{
Receiver receiver = Receiver();
ConcreteCommand command = ConcreteCommand(&receiver);
Invoker invoker = Invoker();
invoker.set(&command);
ConcreteCommand command( new Receiver() );
Invoker invoker;
invoker.set( &command );
invoker.confirm();
return 0;
}

View File

@@ -16,13 +16,19 @@
* defines an interface for all objects in the composition
* both the composite and the leaf nodes
*/
class Component {
class Component
{
public:
virtual Component *getChild(int) { return 0; }
virtual void add(Component *) { /* ... */ }
virtual void remove(int) { /* ... */ }
virtual ~Component() {}
virtual Component *getChild( int )
{
return 0;
}
virtual void add( Component * ) { /* ... */ }
virtual void remove( int ) { /* ... */ }
virtual void operation() = 0;
};
@@ -31,28 +37,44 @@ public:
* defines behavior of the components having children
* and store child components
*/
class Composite : public Component {
class Composite : public Component
{
public:
Component *getChild(int index) {
return children.at(index);
}
void add(Component *component) {
children.push_back(component);
}
void remove(int index) {
children.erase(children.begin() + index);
}
void operation() {
for (unsigned int i = 0; i < children.size(); i++) {
children.at(i)->operation();
~Composite()
{
for ( unsigned int i = 0; i < children.size(); i++ )
{
delete children[ i ];
}
}
Component *getChild( const unsigned int index )
{
return children[ index ];
}
void add( Component *component )
{
children.push_back( component );
}
void remove( const unsigned int index )
{
Component *child = children[ index ];
children.erase( children.begin() + index );
delete child;
}
void operation()
{
for ( unsigned int i = 0; i < children.size(); i++ )
{
children[ i ]->operation();
}
}
private:
std::vector<Component *> children;
std::vector<Component*> children;
};
/*
@@ -60,11 +82,15 @@ private:
* defines the behavior for the elements in the composition,
* it has no children
*/
class Leaf : public Component {
class Leaf : public Component
{
public:
Leaf(int i) : id(i) {}
void operation() {
Leaf( const int i ) : id( i ) {}
~Leaf() {}
void operation()
{
std::cout << "Leaf "<< id <<" operation" << std::endl;
}
@@ -76,12 +102,14 @@ private:
int main()
{
Composite composite;
for (unsigned int i = 0; i < 10; i++) {
composite.add(new Leaf(i));
for ( unsigned int i = 0; i < 5; i++ )
{
composite.add( new Leaf( i ) );
}
composite.remove( 0 );
composite.operation();
return 0;
}

View File

@@ -15,8 +15,11 @@
* defines an interface for objects that can have responsibilities
* added to them dynamically
*/
class Component {
class Component
{
public:
virtual ~Component() {}
virtual void operation() = 0;
// ...
};
@@ -26,9 +29,13 @@ public:
* defines an object to which additional responsibilities
* can be attached
*/
class ConcreteComponent : public Component {
class ConcreteComponent : public Component
{
public:
void operation() {
~ConcreteComponent() {}
void operation()
{
std::cout << "Concrete Component operation" << std::endl;
}
// ...
@@ -39,12 +46,15 @@ public:
* maintains a reference to a Component object and defines an interface
* that conforms to Component's interface
*/
class Decorator : public Component {
class Decorator : public Component
{
public:
Decorator(Component *c)
: component(c) {}
virtual void operation() {
~Decorator() {}
Decorator( Component *c ) : component( c ) {}
virtual void operation()
{
component->operation();
}
// ...
@@ -58,24 +68,26 @@ private:
* add responsibilities to the component (can extend the state
* of the component)
*/
class ConcreteDecoratorA : public Decorator {
class ConcreteDecoratorA : public Decorator
{
public:
ConcreteDecoratorA(Component *c)
: Decorator(c) {}
void operation() {
ConcreteDecoratorA( Component *c ) : Decorator( c ) {}
void operation()
{
Decorator::operation();
std::cout << "Decorator A" << std::endl;
}
// ...
};
class ConcreteDecoratorB : public Decorator {
class ConcreteDecoratorB : public Decorator
{
public:
ConcreteDecoratorB(Component *c)
: Decorator(c) {}
void operation() {
ConcreteDecoratorB( Component *c ) : Decorator( c ) {}
void operation()
{
Decorator::operation();
std::cout << "Decorator B" << std::endl;
}
@@ -85,10 +97,16 @@ public:
int main()
{
Component *component = new ConcreteDecoratorA(
new ConcreteDecoratorB(new ConcreteComponent));
ConcreteComponent *cc = new ConcreteComponent();
ConcreteDecoratorB *db = new ConcreteDecoratorB( cc );
ConcreteDecoratorA *da = new ConcreteDecoratorA( db );
Component *component = da;
component->operation();
delete da;
delete db;
delete cc;
return 0;
}

View File

@@ -15,27 +15,33 @@
* implement more complex subsystem functionality
* and have no knowledge of the facade
*/
class SubsystemA {
class SubsystemA
{
public:
void suboperation() {
void suboperation()
{
std::cout << "Subsystem A method" << std::endl;
// ...
}
// ...
};
class SubsystemB {
class SubsystemB
{
public:
void suboperation() {
void suboperation()
{
std::cout << "Subsystem B method" << std::endl;
// ...
}
// ...
};
class SubsystemC {
class SubsystemC
{
public:
void suboperation() {
void suboperation()
{
std::cout << "Subsystem C method" << std::endl;
// ...
}
@@ -47,24 +53,25 @@ public:
* delegates client requests to appropriate subsystem object
* and unified interface that is easier to use
*/
class Facade {
class Facade
{
public:
Facade() :
subsystemA(), subsystemB(), subsystemC() {}
void operation1() {
Facade() : subsystemA(), subsystemB(), subsystemC() {}
void operation1()
{
subsystemA->suboperation();
subsystemB->suboperation();
// ...
}
void operation2() {
void operation2()
{
subsystemC->suboperation();
// ...
}
// ...
private:
SubsystemA *subsystemA;
SubsystemB *subsystemB;
@@ -76,8 +83,10 @@ private:
int main()
{
Facade *facade = new Facade();
facade->operation1();
facade->operation2();
delete facade;
return 0;
}

View File

@@ -15,8 +15,11 @@
* products implement the same interface so that the classes can refer
* to the interface not the concrete product
*/
class Product {
class Product
{
public:
virtual ~Product() {}
virtual std::string getName() = 0;
// ...
};
@@ -25,9 +28,13 @@ public:
* Concrete Product
* define product to be created
*/
class ConcreteProductA : public Product {
class ConcreteProductA : public Product
{
public:
std::string getName() {
~ConcreteProductA() {}
std::string getName()
{
return "type A";
}
// ...
@@ -37,9 +44,13 @@ public:
* Concrete Product
* define product to be created
*/
class ConcreteProductB : public Product {
class ConcreteProductB : public Product
{
public:
std::string getName() {
~ConcreteProductB() {}
std::string getName()
{
return "type B";
}
// ...
@@ -50,10 +61,16 @@ public:
* contains the implementation for all of the methods
* to manipulate products except for the factory method
*/
class Creator {
class Creator
{
public:
virtual ~Creator() {}
virtual Product* createProductA() = 0;
virtual Product* createProductB() = 0;
virtual void removeProduct( Product *product ) = 0;
// ...
};
@@ -63,15 +80,25 @@ public:
* one or more concrete products ie. it is class that has
* the knowledge of how to create the products
*/
class ConcreteCreator : public Creator {
class ConcreteCreator : public Creator
{
public:
Product* createProductA() {
~ConcreteCreator() {}
Product* createProductA()
{
return new ConcreteProductA();
}
Product* createProductB() {
Product* createProductB()
{
return new ConcreteProductB();
}
void removeProduct( Product *product )
{
delete product;
}
// ...
};
@@ -79,12 +106,15 @@ public:
int main()
{
Creator *creator = new ConcreteCreator();
Product *p1 = creator->createProductA();
std::cout << "Product: " << p1->getName() << std::endl;
creator->removeProduct( p1 );
Product *p2 = creator->createProductB();
std::cout << "Product: " << p2->getName() << std::endl;
creator->removeProduct( p2 );
delete creator;
return 0;
}

View File

@@ -16,9 +16,10 @@
* declares an interface through which flyweights can receive
* and act on extrinsic state
*/
class Flyweight {
class Flyweight
{
public:
virtual ~Flyweight() { /* ... */ }
virtual ~Flyweight() {}
virtual void operation() = 0;
// ...
};
@@ -27,16 +28,20 @@ public:
* UnsharedConcreteFlyweight
* not all subclasses need to be shared
*/
class UnsharedConcreteFlyweight : public Flyweight {
class UnsharedConcreteFlyweight : public Flyweight
{
public:
UnsharedConcreteFlyweight(int intrinsic_state) :
state(intrinsic_state) {}
void operation() {
UnsharedConcreteFlyweight( const int intrinsic_state ) :
state( intrinsic_state ) {}
~UnsharedConcreteFlyweight() {}
void operation()
{
std::cout << "Unshared Flyweight with state " << state << std::endl;
}
// ...
private:
int state;
// ...
@@ -47,16 +52,20 @@ private:
* implements the Flyweight interface and adds storage
* for intrinsic state
*/
class ConcreteFlyweight : public Flyweight {
class ConcreteFlyweight : public Flyweight
{
public:
ConcreteFlyweight(int all_state) :
state(all_state) {}
void operation() {
ConcreteFlyweight( const int all_state ) :
state( all_state ) {}
~ConcreteFlyweight() {}
void operation()
{
std::cout << "Concrete Flyweight with state " << state << std::endl;
}
// ...
private:
int state;
// ...
@@ -67,27 +76,32 @@ private:
* creates and manages flyweight objects and ensures
* that flyweights are shared properly
*/
class FlyweightFactory {
class FlyweightFactory
{
public:
virtual ~FlyweightFactory() {
for (auto it = flies.begin(); it != flies.end(); it++) {
~FlyweightFactory()
{
for ( auto it = flies.begin(); it != flies.end(); it++ )
{
delete it->second;
}
flies.clear();
}
Flyweight *getFlyweight(int key) {
if (flies.find(key) != flies.end()) {
return flies[key];
Flyweight *getFlyweight( const int key )
{
if ( flies.find( key ) != flies.end() )
{
return flies[ key ];
}
Flyweight *fly = new ConcreteFlyweight(key);
flies.insert(std::pair<int, Flyweight *>(key, fly));
Flyweight *fly = new ConcreteFlyweight( key );
flies.insert( std::pair<int, Flyweight *>( key, fly ) );
return fly;
}
// ...
private:
std::map<int, Flyweight *> flies;
std::map<int, Flyweight*> flies;
// ...
};
@@ -97,6 +111,6 @@ int main()
FlyweightFactory *factory = new FlyweightFactory;
factory->getFlyweight(1)->operation();
factory->getFlyweight(2)->operation();
delete factory;
return 0;
}

View File

@@ -15,14 +15,17 @@
* Context
* contains information that's global to the interpreter
*/
class Context {
class Context
{
public:
void set(std::string var, bool value) {
vars.insert(std::pair<std::string, bool>(var, value));
void set( const std::string& var, const bool value)
{
vars.insert( std::pair<std::string, bool>( var, value ) );
}
bool get(std::string exp) {
return vars[exp];
bool get( const std::string& exp )
{
return vars[ exp ];
}
// ...
@@ -36,10 +39,13 @@ private:
* declares an abstract Interpret operation that is common to all nodes
* in the abstract syntax tree
*/
class AbstractExpression {
class AbstractExpression
{
public:
virtual ~AbstractExpression() {}
virtual bool interpret(Context *) {
virtual bool interpret( Context* const )
{
return false;
}
// ...
@@ -51,18 +57,19 @@ public:
* in the grammar (an instance is required for every terminal symbol
* in a sentence)
*/
class TerminalExpression : public AbstractExpression {
class TerminalExpression : public AbstractExpression
{
public:
TerminalExpression(std::string val)
: value(val) {}
TerminalExpression( const std::string& val ) : value( val ) {}
~TerminalExpression() {}
bool interpret(Context *context) {
return context->get(value);
bool interpret( Context* const context )
{
return context->get( value );
}
// ...
private:
std::string value;
// ...
@@ -73,21 +80,24 @@ private:
* implements an Interpret operation for nonterminal symbols
* in the grammar (one such class is required for every rule in the grammar)
*/
class NonterminalExpression : public AbstractExpression {
class NonterminalExpression : public AbstractExpression
{
public:
NonterminalExpression(AbstractExpression *left, AbstractExpression *right)
: lop(left), rop(right) {}
~NonterminalExpression() {
NonterminalExpression( AbstractExpression *left, AbstractExpression *right ) :
lop( left ), rop( right ) {}
~NonterminalExpression()
{
delete lop;
delete rop;
}
bool interpret(Context *context) {
return lop->interpret(context) && rop->interpret(context);
bool interpret( Context *const context )
{
return lop->interpret( context ) && rop->interpret( context );
}
// ...
private:
AbstractExpression *lop;
AbstractExpression *rop;
@@ -101,15 +111,15 @@ int main()
// that corresponds to expression (A AND B)
AbstractExpression *A = new TerminalExpression("A");
AbstractExpression *B = new TerminalExpression("B");
AbstractExpression *exp = new NonterminalExpression(A, B);
AbstractExpression *exp = new NonterminalExpression( A, B );
Context context;
context.set("A", true);
context.set("B", false);
std::cout << context.get("A") << " AND " << context.get("B");
std::cout << " = " << exp->interpret(&context) << std::endl;
context.set( "A", true );
context.set( "B", false );
std::cout << context.get( "A" ) << " AND " << context.get( "B" );
std::cout << " = " << exp->interpret( &context ) << std::endl;
delete exp;
return 0;
}

View File

@@ -20,8 +20,11 @@ class ConcreteAggregate;
* defines an interface for aggregates and it decouples your
* client from the implementation of your collection of objects
*/
class Aggregate {
class Aggregate
{
public:
virtual ~Aggregate() {}
virtual Iterator *createIterator() = 0;
// ...
};
@@ -32,25 +35,30 @@ public:
* that returns an Iterator for its collection
*
*/
class ConcreteAggregate : public Aggregate {
class ConcreteAggregate : public Aggregate
{
public:
ConcreteAggregate(const unsigned int size) {
ConcreteAggregate( const unsigned int size )
{
list = new int[size]();
count = size;
}
Iterator *createIterator();
~ConcreteAggregate() {
~ConcreteAggregate()
{
delete[] list;
}
unsigned int size() const {
Iterator *createIterator();
unsigned int size() const
{
return count;
}
int at(unsigned int index) {
return list[index];
int at( unsigned int index )
{
return list[ index ];
}
// ...
@@ -65,10 +73,11 @@ private:
* provides the interface that all iterators must implement and
* a set of methods for traversing over elements
*/
class Iterator {
class Iterator
{
public:
virtual ~Iterator() { /* ... */ }
virtual void first() = 0;
virtual void next() = 0;
virtual bool isDone() const = 0;
@@ -81,25 +90,33 @@ public:
* implements the interface and is responsible for managing
* the current position of the iterator
*/
class ConcreteIterator : public Iterator {
class ConcreteIterator : public Iterator
{
public:
ConcreteIterator(ConcreteAggregate *l)
: list(l), index(0) {}
void first() {
ConcreteIterator( ConcreteAggregate *l ) :
list( l ), index( 0 ) {}
~ConcreteIterator() {}
void first()
{
index = 0;
}
void next() {
void next()
{
index++;
}
bool isDone() const {
return (index >= list->size());
bool isDone() const
{
return ( index >= list->size() );
}
int currentItem() const {
if (isDone()) {
int currentItem() const
{
if ( isDone() )
{
return -1;
}
return list->at(index);
@@ -112,21 +129,23 @@ private:
// ...
};
Iterator *ConcreteAggregate::createIterator() {
return new ConcreteIterator(this);
Iterator *ConcreteAggregate::createIterator()
{
return new ConcreteIterator( this );
}
int main()
{
unsigned int size = 5;
ConcreteAggregate list = ConcreteAggregate(size);
ConcreteAggregate list = ConcreteAggregate( size );
Iterator *it = list.createIterator();
for ( ; !it->isDone(); it->next()) {
for ( ; !it->isDone(); it->next())
{
std::cout << "Item value: " << it->currentItem() << std::endl;
}
delete it;
return 0;
}
}

View File

@@ -18,33 +18,39 @@ class Mediator;
* each colleague communicates with its mediator whenever
* it would have otherwise communicated with another colleague
*/
class Colleague {
class Colleague
{
public:
Colleague(Mediator *m, unsigned int i)
: mediator(m), id(i) {}
Colleague( Mediator* const m, const unsigned int i ) :
mediator( m ), id( i ) {}
virtual ~Colleague() {}
unsigned int getID() {
unsigned int getID()
{
return id;
}
virtual void send(std::string) = 0;
virtual void receive(std::string) = 0;
virtual void send( std::string ) = 0;
virtual void receive( std::string ) = 0;
protected:
Mediator *mediator;
unsigned int id;
};
class ConcreteColleague : public Colleague {
class ConcreteColleague : public Colleague
{
public:
ConcreteColleague(Mediator *m, unsigned int i)
: Colleague(m, i) {}
void send(std::string msg);
void receive(std::string msg) {
ConcreteColleague( Mediator* const m, const unsigned int i ) :
Colleague( m, i ) {}
~ConcreteColleague() {}
void send( std::string msg );
void receive( std::string msg )
{
std::cout << "Message '" << msg << "' received by Colleague " << id << std::endl;
}
};
@@ -53,12 +59,13 @@ public:
* Mediator
* defines an interface for communicating with Colleague objects
*/
class Mediator {
class Mediator
{
public:
virtual ~Mediator() {}
virtual void add(Colleague *c) = 0;
virtual void distribute(Colleague *sender, std::string msg) = 0;
virtual void add( Colleague* const c ) = 0;
virtual void distribute( Colleague* const sender, std::string msg ) = 0;
protected:
Mediator() {}
@@ -69,52 +76,60 @@ protected:
* implements cooperative behavior by coordinating Colleague objects
* and knows its colleagues
*/
class ConcreteMediator : public Mediator {
class ConcreteMediator : public Mediator
{
public:
~ConcreteMediator() {
for (unsigned int i = 0; i < colleagues.size(); i++) {
delete colleagues[i];
~ConcreteMediator()
{
for ( unsigned int i = 0; i < colleagues.size(); i++ )
{
delete colleagues[ i ];
}
colleagues.clear();
}
void add(Colleague *c) {
colleagues.push_back(c);
void add( Colleague* const c )
{
colleagues.push_back( c );
}
void distribute(Colleague *sender, std::string msg) {
for (unsigned int i = 0; i < colleagues.size(); i++) {
if (colleagues.at(i)->getID() != sender->getID()) {
colleagues.at(i)->receive(msg);
void distribute( Colleague* const sender, std::string msg )
{
for ( unsigned int i = 0; i < colleagues.size(); i++ )
{
if ( colleagues.at( i )->getID() != sender->getID() )
{
colleagues.at( i )->receive( msg );
}
}
}
private:
std::vector<Colleague *> colleagues;
std::vector<Colleague*> colleagues;
};
void ConcreteColleague::send(std::string msg) {
void ConcreteColleague::send( std::string msg )
{
std::cout << "Message '"<< msg << "' sent by Colleague " << id << std::endl;
mediator->distribute(this, msg);
mediator->distribute( this, msg );
}
int main()
{
Mediator *mediator = new ConcreteMediator;
Colleague *c1 = new ConcreteColleague(mediator, 1);
Colleague *c2 = new ConcreteColleague(mediator, 2);
Colleague *c3 = new ConcreteColleague(mediator, 3);
mediator->add(c1);
mediator->add(c2);
mediator->add(c3);
c1->send("Hi!");
c3->send("Hello!");
Mediator *mediator = new ConcreteMediator();
Colleague *c1 = new ConcreteColleague( mediator, 1 );
Colleague *c2 = new ConcreteColleague( mediator, 2 );
Colleague *c3 = new ConcreteColleague( mediator, 3 );
mediator->add( c1 );
mediator->add( c2 );
mediator->add( c3 );
c1->send( "Hi!" );
c3->send( "Hello!" );
delete mediator;
return 0;
}

View File

@@ -16,19 +16,21 @@
* stores internal state of the Originator object and protects
* against access by objects other than the originator
*/
class Memento {
class Memento
{
private:
// accessible only to Originator
friend class Originator;
Memento(int s)
: state(s) {}
void setState(int s) {
Memento( const int s ) : state( s ) {}
void setState( const int s )
{
state = s;
}
int getState() {
int getState()
{
return state;
}
// ...
@@ -43,25 +45,30 @@ private:
* creates a memento containing a snapshot of its current internal
* state and uses the memento to restore its internal state
*/
class Originator {
class Originator
{
public:
// implemented only for printing purpose
void setState(int s) {
void setState( const int s )
{
std::cout << "Set state to " << s << "." << std::endl;
state = s;
}
// implemented only for printing purpose
int getState() {
int getState()
{
return state;
}
void setMemento(Memento *m) {
void setMemento( Memento* const m )
{
state = m->getState();
}
Memento *createMemento() {
return new Memento(state);
Memento *createMemento()
{
return new Memento( state );
}
private:
@@ -73,55 +80,68 @@ private:
* CareTaker
* is responsible for the memento's safe keeping
*/
class CareTaker {
class CareTaker
{
public:
CareTaker(Originator *o)
: originator(o) {}
~CareTaker() {
for (unsigned int i = 0; i < history.size(); i++) {
delete history.at(i);
CareTaker( Originator* const o ) : originator( o ) {}
~CareTaker()
{
for ( unsigned int i = 0; i < history.size(); i++ )
{
delete history.at( i );
}
history.clear();
}
void save() {
std::cout << "Save state." << std::endl;;
history.push_back(originator->createMemento());
void save()
{
std::cout << "Save state." << std::endl;
history.push_back( originator->createMemento() );
}
void undo() {
std::cout << "Undo state." << std::endl;;
originator->setMemento(history.back());
void undo()
{
if ( history.empty() )
{
std::cout << "Unable to undo state." << std::endl;
return;
}
Memento *m = history.back();
originator->setMemento( m );
std::cout << "Undo state." << std::endl;
history.pop_back();
delete m;
}
// ...
private:
Originator *originator;
std::vector<Memento *> history;
std::vector<Memento*> history;
// ...
};
int main()
{
Originator *originator = new Originator;
CareTaker *caretaker = new CareTaker(originator);
originator->setState(1);
Originator *originator = new Originator();
CareTaker *caretaker = new CareTaker( originator );
originator->setState( 1 );
caretaker->save();
originator->setState(2);
originator->setState( 2 );
caretaker->save();
originator->setState(3);
originator->setState( 3 );
caretaker->undo();
std::cout << "Actual state is " << originator->getState() << "." << std::endl;
delete originator;
delete caretaker;
return 0;
}

View File

@@ -18,10 +18,13 @@ class Subject;
* defines an updating interface for objects that should be notified
* of changes in a subject
*/
class Observer {
class Observer
{
public:
virtual ~Observer() {}
virtual int getState() = 0;
virtual void update(Subject *subject) = 0;
virtual void update( Subject *subject ) = 0;
// ...
};
@@ -30,16 +33,20 @@ public:
* stores state of interest to ConcreteObserver objects and
* sends a notification to its observers when its state changes
*/
class ConcreteObserver : public Observer {
class ConcreteObserver : public Observer
{
public:
ConcreteObserver(int state)
: observer_state(state) {}
int getState() {
ConcreteObserver( const int state ) :
observer_state( state ) {}
~ConcreteObserver() {}
int getState()
{
return observer_state;
}
void update(Subject *subject);
void update( Subject *subject );
// ...
private:
@@ -52,28 +59,35 @@ private:
* knows its observers and provides an interface for attaching
* and detaching observers
*/
class Subject {
class Subject
{
public:
void attach(Observer *observer) {
virtual ~Subject() {}
void attach( Observer *observer )
{
observers.push_back(observer);
}
void detach(int index) {
observers.erase(observers.begin() + index);
void detach( const int index )
{
observers.erase( observers.begin() + index );
}
void notify() {
for (unsigned int i = 0; i < observers.size(); i++) {
observers.at(i)->update(this);
void notify()
{
for ( unsigned int i = 0; i < observers.size(); i++ )
{
observers.at( i )->update( this );
}
}
virtual int getState() = 0;
virtual void setState(int s) = 0;
virtual void setState( const int s ) = 0;
// ...
private:
std::vector<Observer *> observers;
std::vector<Observer*> observers;
// ...
};
@@ -81,23 +95,29 @@ private:
* Concrete Subject
* stores state that should stay consistent with the subject's
*/
class ConcreteSubject : public Subject {
class ConcreteSubject : public Subject
{
public:
int getState() {
~ConcreteSubject() {}
int getState()
{
return subject_state;
}
void setState(int s) {
void setState( const int s )
{
subject_state = s;
}
// ...
private:
int subject_state;
// ...
};
void ConcreteObserver::update(Subject *subject) {
void ConcreteObserver::update( Subject *subject )
{
observer_state = subject->getState();
std::cout << "Observer state updated." << std::endl;
}
@@ -105,21 +125,22 @@ void ConcreteObserver::update(Subject *subject) {
int main()
{
ConcreteObserver observer1(1);
ConcreteObserver observer2(2);
ConcreteObserver observer1( 1 );
ConcreteObserver observer2( 2 );
std::cout << "Observer 1 state: " << observer1.getState() << std::endl;
std::cout << "Observer 2 state: " << observer2.getState() << std::endl;
Subject *subject = new ConcreteSubject;
subject->attach(&observer1);
subject->attach(&observer2);
subject->setState(10);
Subject *subject = new ConcreteSubject();
subject->attach( &observer1 );
subject->attach( &observer2 );
subject->setState( 10 );
subject->notify();
std::cout << "Observer 1 state: " << observer1.getState() << std::endl;
std::cout << "Observer 2 state: " << observer2.getState() << std::endl;
delete subject;
return 0;
}
}

View File

@@ -14,9 +14,12 @@
* Prototype
* declares an interface for cloning itself
*/
class Prototype {
class Prototype
{
public:
virtual Prototype *clone() = 0;
virtual ~Prototype() {}
virtual Prototype* clone() = 0;
virtual std::string type() = 0;
// ...
};
@@ -25,23 +28,33 @@ public:
* Concrete Prototype A and B
* implement an operation for cloning itself
*/
class ConcretePrototypeA : public Prototype {
class ConcretePrototypeA : public Prototype
{
public:
Prototype *clone() {
return new ConcretePrototypeA;
~ConcretePrototypeA() {}
Prototype* clone()
{
return new ConcretePrototypeA();
}
std::string type() {
std::string type()
{
return "type A";
}
// ...
};
class ConcretePrototypeB : public Prototype {
class ConcretePrototypeB : public Prototype
{
public:
Prototype *clone() {
return new ConcretePrototypeB;
~ConcretePrototypeB() {}
Prototype* clone()
{
return new ConcretePrototypeB();
}
std::string type() {
std::string type()
{
return "type B";
}
// ...
@@ -51,34 +64,52 @@ public:
* Client
* creates a new object by asking a prototype to clone itself
*/
class Client {
class Client
{
public:
static Prototype* make(int index) {
return types[index]->clone();
static void init()
{
types[ 0 ] = new ConcretePrototypeA();
types[ 1 ] = new ConcretePrototypeB();
}
static void remove()
{
delete types[ 0 ];
delete types[ 1 ];
}
static Prototype* make( const int index )
{
if ( index >= n_types )
{
return nullptr;
}
return types[ index ]->clone();
}
// ...
private:
static Prototype* types[2];
};
Prototype* Client::types[] =
{
new ConcretePrototypeA,
new ConcretePrototypeB
// ...
static Prototype* types[ 2 ];
static int n_types;
};
Prototype* Client::types[ 2 ];
int Client::n_types = 2;
int main()
{
Prototype* prototype;
prototype = Client::make(0);
std::cout << "Prototype: " << prototype->type() << std::endl;
prototype = Client::make(1);
std::cout << "Prototype: " << prototype->type() << std::endl;
Client::init();
Prototype *prototype1 = Client::make( 0 );
std::cout << "Prototype: " << prototype1->type() << std::endl;
delete prototype1;
Prototype *prototype2 = Client::make( 1 );
std::cout << "Prototype: " << prototype2->type() << std::endl;
delete prototype2;
Client::remove();
return 0;
}

View File

@@ -15,7 +15,8 @@
* defines the common interface for RealSubject and Proxy
* so that a Proxy can be used anywhere a RealSubject is expected
*/
class Subject {
class Subject
{
public:
virtual ~Subject() { /* ... */ }
@@ -27,9 +28,11 @@ public:
* Real Subject
* defines the real object that the proxy represents
*/
class RealSubject : public Subject {
class RealSubject : public Subject
{
public:
void request() {
void request()
{
std::cout << "Real Subject request" << std::endl;
}
// ...
@@ -39,17 +42,21 @@ public:
* Proxy
* maintains a reference that lets the proxy access the real subject
*/
class Proxy : public Subject {
class Proxy : public Subject
{
public:
Proxy() {
Proxy()
{
subject = new RealSubject();
}
~Proxy() {
~Proxy()
{
delete subject;
}
void request() {
void request()
{
subject->request();
}
// ...
@@ -61,8 +68,9 @@ private:
int main()
{
Proxy *proxy = new Proxy;
Proxy *proxy = new Proxy();
proxy->request();
delete proxy;
return 0;
}

View File

@@ -15,16 +15,28 @@
* has private static variable to hold one instance of the class
* and method which gives us a way to instantiate the class
*/
class Singleton {
class Singleton
{
public:
static Singleton *get() {
if (instance == NULL) {
static Singleton* get()
{
if ( !instance )
{
instance = new Singleton();
}
}
return instance;
}
void tell() {
static void restart()
{
if ( instance )
{
delete instance;
}
}
void tell()
{
std::cout << "This is Singleton." << std::endl;
// ...
}
@@ -42,5 +54,7 @@ Singleton* Singleton::instance = nullptr;
int main()
{
Singleton::get()->tell();
Singleton::restart();
return 0;
}

View File

@@ -15,7 +15,8 @@
* defines an interface for encapsulating the behavior associated
* with a particular state of the Context
*/
class State {
class State
{
public:
virtual ~State() { /* ... */ }
virtual void handle() = 0;
@@ -27,21 +28,25 @@ public:
* each subclass implements a behavior associated with a state
* of the Context
*/
class ConcreteStateA : public State {
class ConcreteStateA : public State
{
public:
~ConcreteStateA() { /* ... */ }
void handle() {
void handle()
{
std::cout << "State A handled." << std::endl;
}
// ...
};
class ConcreteStateB : public State {
class ConcreteStateB : public State
{
public:
~ConcreteStateB() { /* ... */ }
void handle() {
void handle()
{
std::cout << "State B handled." << std::endl;
}
// ...
@@ -51,22 +56,27 @@ public:
* Context
* defines the interface of interest to clients
*/
class Context {
class Context
{
public:
Context() : state() { /* ... */ }
~Context() {
~Context()
{
delete state;
}
void setState(State *s) {
if (state) {
void setState( State* const s )
{
if ( state )
{
delete state;
}
state = s;
}
void request() {
void request()
{
state->handle();
}
// ...
@@ -79,17 +89,14 @@ private:
int main()
{
State *stateA = new ConcreteStateA;
State *stateB = new ConcreteStateB;
Context *context = new Context;
context->setState(stateA);
Context *context = new Context();
context->setState( new ConcreteStateA() );
context->request();
context->setState(stateB);
context->setState( new ConcreteStateB() );
context->request();
delete context;
return 0;
}

View File

@@ -14,7 +14,8 @@
* Strategy
* declares an interface common to all supported algorithms
*/
class Strategy {
class Strategy
{
public:
virtual ~Strategy() { /* ... */ }
virtual void algorithmInterface() = 0;
@@ -25,31 +26,37 @@ public:
* Concrete Strategies
* implement the algorithm using the Strategy interface
*/
class ConcreteStrategyA : public Strategy {
class ConcreteStrategyA : public Strategy
{
public:
~ConcreteStrategyA() { /* ... */ }
void algorithmInterface() {
void algorithmInterface()
{
std::cout << "Concrete Strategy A" << std::endl;
}
// ...
};
class ConcreteStrategyB : public Strategy {
class ConcreteStrategyB : public Strategy
{
public:
~ConcreteStrategyB() { /* ... */ }
void algorithmInterface() {
void algorithmInterface()
{
std::cout << "Concrete Strategy B" << std::endl;
}
// ...
};
class ConcreteStrategyC : public Strategy {
class ConcreteStrategyC : public Strategy
{
public:
~ConcreteStrategyC() { /* ... */ }
void algorithmInterface() {
void algorithmInterface()
{
std::cout << "Concrete Strategy C" << std::endl;
}
// ...
@@ -59,16 +66,18 @@ public:
* Context
* maintains a reference to a Strategy object
*/
class Context {
class Context
{
public:
Context(Strategy *s)
: strategy(s) {}
~Context() {
Context( Strategy* const s ) : strategy( s ) {}
~Context()
{
delete strategy;
}
void contextInterface() {
void contextInterface()
{
strategy->algorithmInterface();
}
// ...
@@ -81,12 +90,8 @@ private:
int main()
{
ConcreteStrategyA strategy;
// ConcreteStrategyB strategy;
// ConcreteStrategyC strategy;
Context context(&strategy);
Context context( new ConcreteStrategyA() );
context.contextInterface();
return 0;
}

View File

@@ -14,16 +14,20 @@
* AbstractClass
* implements a template method defining the skeleton of an algorithm
*/
class AbstractClass {
class AbstractClass
{
public:
void templateMethod() {
virtual ~AbstractClass() {}
void templateMethod()
{
// ...
primitiveOperation1();
// ...
primitiveOperation2();
// ...
}
virtual void primitiveOperation1() = 0;
virtual void primitiveOperation2() = 0;
// ...
@@ -35,14 +39,19 @@ public:
* of the algorithm, there may be many Concrete classes, each implementing
* the full set of the required operation
*/
class ConcreteClass : public AbstractClass {
class ConcreteClass : public AbstractClass
{
public:
void primitiveOperation1() {
~ConcreteClass() {}
void primitiveOperation1()
{
std::cout << "Primitive operation 1" << std::endl;
// ...
}
void primitiveOperation2() {
void primitiveOperation2()
{
std::cout << "Primitive operation 2" << std::endl;
// ...
}
@@ -54,6 +63,7 @@ int main()
{
AbstractClass *tm = new ConcreteClass;
tm->templateMethod();
delete tm;
return 0;
}

View File

@@ -19,10 +19,13 @@ class ConcreteElementB;
* declares a Visit operation for each class of ConcreteElement
* in the object structure
*/
class Visitor {
class Visitor
{
public:
virtual void visitElementA(ConcreteElementA *element) = 0;
virtual void visitElementB(ConcreteElementB *element) = 0;
virtual ~Visitor() {}
virtual void visitElementA( ConcreteElementA* const element ) = 0;
virtual void visitElementB( ConcreteElementB* const element ) = 0;
// ...
};
@@ -32,25 +35,35 @@ public:
* a fragment of the algorithm defined for the corresponding class
* of object in the structure
*/
class ConcreteVisitor1 : public Visitor {
class ConcreteVisitor1 : public Visitor
{
public:
void visitElementA(ConcreteElementA *) {
~ConcreteVisitor1() {}
void visitElementA( ConcreteElementA* const )
{
std::cout << "Concrete Visitor 1: Element A visited." << std::endl;
}
void visitElementB(ConcreteElementB *) {
void visitElementB( ConcreteElementB* const )
{
std::cout << "Concrete Visitor 1: Element B visited." << std::endl;
}
// ...
};
class ConcreteVisitor2 : public Visitor {
class ConcreteVisitor2 : public Visitor
{
public:
void visitElementA(ConcreteElementA *) {
~ConcreteVisitor2() {}
void visitElementA( ConcreteElementA* const )
{
std::cout << "Concrete Visitor 2: Element A visited." << std::endl;
}
void visitElementB(ConcreteElementB *) {
void visitElementB( ConcreteElementB* const )
{
std::cout << "Concrete Visitor 2: Element B visited." << std::endl;
}
// ...
@@ -60,9 +73,12 @@ public:
* Element
* defines an accept operation that takes a visitor as an argument
*/
class Element {
class Element
{
public:
virtual void accept(Visitor &visitor) = 0;
virtual ~Element() {}
virtual void accept( Visitor &visitor ) = 0;
// ...
};
@@ -70,18 +86,26 @@ public:
* Concrete Elements
* implement an accept operation that takes a visitor as an argument
*/
class ConcreteElementA : public Element {
class ConcreteElementA : public Element
{
public:
void accept(Visitor &visitor) {
visitor.visitElementA(this);
~ConcreteElementA() {}
void accept( Visitor &visitor )
{
visitor.visitElementA( this );
}
// ...
};
class ConcreteElementB : public Element {
class ConcreteElementB : public Element
{
public:
void accept(Visitor &visitor) {
visitor.visitElementB(this);
~ConcreteElementB() {}
void accept( Visitor &visitor )
{
visitor.visitElementB( this );
}
// ...
};
@@ -91,15 +115,15 @@ int main()
{
ConcreteElementA elementA;
ConcreteElementB elementB;
ConcreteVisitor1 visitor1;
ConcreteVisitor2 visitor2;
elementA.accept(visitor1);
elementA.accept(visitor2);
elementB.accept(visitor1);
elementB.accept(visitor2);
return 0;
}