This document outlines an advanced C++ programming seminar on design patterns given in 2009. It introduces the singleton, monostate, and bridge patterns. For the singleton pattern, it discusses ensuring a class only has one instance, motivations for its use, different implementations (naive, correct, Meyers), and solutions to resource leaks such as the phoenix singleton.
This document outlines an advanced C++ programming seminar on design patterns given in 2009. It introduces the singleton, monostate, and bridge patterns. For the singleton pattern, it discusses ensuring a class only has one instance, motivations for its use, different implementations (naive, correct, Meyers), and solutions to resource leaks such as the phoenix singleton.
Advanced C++ Programming Seminar, Summer Term 2009
Georg Altmann University Erlangen-Nuremberg System Simulation June 4th 2009 Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 1 / 48 Outline Introduction The Singleton Pattern The Monostate Pattern The Bridge Pattern Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 2 / 48 What is a Design Pattern? Design Patterns are descriptions of communicating objects and classes that are customized to solve a general design problem in a particular context. a a Erich Gamma [et al.], Design Patterns, Addison Wesley, 1994 Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 3 / 48 Why use Design Patterns? Design Patterns are proven solutions to re-occurring software design problems Dont re-invent the wheel! Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 4 / 48 Outline Introduction The Singleton Pattern The Monostate Pattern The Bridge Pattern Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 5 / 48 The Singleton Pattern The Problem Ensure a class has only one instance with global access Motivation For some classes it is important, that only one instance exists: program conguration classes classes representing unique system devices logging classes etc. Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 6 / 48 The Singleton Pattern singleton.h class Singleton { public: // Unique global point of access static Singleton* getInstance(); private: static Singleton* instance_; }; Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 7 / 48 The Singleton Pattern singleton.cpp Singleton* Singleton::instance_ = 0; Singleton* Singleton::getInstance() { if(instance_ == 0) instance_ = new Singleton(); return instance_; } Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 8 / 48 The Singleton Pattern Singleton? class Singleton { public: static Singleton* getInstance(); private: static Singleton* instance_; }; No! Default constructor public: It is possible to create multiple instances! Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 9 / 48 The Singleton Pattern Singleton? class Singleton { public: static Singleton* getInstance(); private: static Singleton* instance_; }; No! Default constructor public: It is possible to create multiple instances! Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 9 / 48 The Singleton Pattern Singleton? class Singleton { public: static Singleton* getInstance(); private: Singleton(); static Singleton* instance_; }; No! Copy constructor and copy assignment operator public: It is still possible to create multiple instances by copying! Singleton myCopy(*Singleton::getInstance()); Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 10 / 48 The Singleton Pattern Singleton? class Singleton { public: static Singleton* getInstance(); private: Singleton(); static Singleton* instance_; }; No! Copy constructor and copy assignment operator public: It is still possible to create multiple instances by copying! Singleton myCopy(*Singleton::getInstance()); Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 10 / 48 The Singleton Pattern Singleton! class Singleton { public: static Singleton* getInstance(); private: Singleton(); Singleton(const Singleton&); // non- Singleton& operator=(const Singleton&); // copyable static Singleton* instance_; }; Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 11 / 48 The Singleton Pattern Singleton gone. . . Singleton *s = Singleton::getInstance(); delete s; // Oops! Destructor is public: Clients can destroy the Singleton. Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 12 / 48 The Singleton Pattern Singleton gone. . . Singleton *s = Singleton::getInstance(); delete s; // Oops! Destructor is public: Clients can destroy the Singleton. Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 12 / 48 The Singleton Pattern A simple Singleton class Singleton { public: static Singleton& getInstance(); // return reference private: Singleton(); Singleton(const Singleton&); // non- Singleton& operator=(const Singleton&); // copyable ~Singleton(); // indestructible static Singleton* instance_; }; Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 13 / 48 The Singleton Pattern Resource leak: Singleton() is never called! Resources held by the Singleton are never freed May be acceptable for dynamically allocated memory OS-wide mutexes, IPC, CORBA/COM problematic! How can the resource leak be avoided? Use a local static variable instead of a static data member a a Meyers, More Eective C++, Addison-Wesley, 1996 Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 14 / 48 The Singleton Pattern Resource leak: Singleton() is never called! Resources held by the Singleton are never freed May be acceptable for dynamically allocated memory OS-wide mutexes, IPC, CORBA/COM problematic! How can the resource leak be avoided? Use a local static variable instead of a static data member a a Meyers, More Eective C++, Addison-Wesley, 1996 Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 14 / 48 The Singleton Pattern Resource leak: Singleton() is never called! Resources held by the Singleton are never freed May be acceptable for dynamically allocated memory OS-wide mutexes, IPC, CORBA/COM problematic! How can the resource leak be avoided? Use a local static variable instead of a static data member a a Meyers, More Eective C++, Addison-Wesley, 1996 Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 14 / 48 The Meyers Singleton class Singleton { public: static Singleton& getInstance(); private: Singleton(); Singleton(const Singleton&); // non- Singleton& Singleton(const Singleton&); // copyable ~Singleton(); // no static instance pointer! }; Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 15 / 48 The Meyers Singleton Singleton& Singleton::getInstance() { static Singleton instance; return instance; } Meyers Singleton Consequences instance initialized when getInstance() is called the rst time instance ist destroyed automatically (std::atexit()) Order of destruction of static objects is arbitrary! Problematic if static objects are interdependent Dead reference problem Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 16 / 48 The Meyers Singleton Singleton& Singleton::getInstance() { static Singleton instance; return instance; } Meyers Singleton Consequences instance initialized when getInstance() is called the rst time instance ist destroyed automatically (std::atexit()) Order of destruction of static objects is arbitrary! Problematic if static objects are interdependent Dead reference problem Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 16 / 48 The Meyers Singleton Singleton& Singleton::getInstance() { static Singleton instance; return instance; } Meyers Singleton Consequences instance initialized when getInstance() is called the rst time instance ist destroyed automatically (std::atexit()) Order of destruction of static objects is arbitrary! Problematic if static objects are interdependent Dead reference problem Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 16 / 48 The Meyers Singleton Singleton& Singleton::getInstance() { static Singleton instance; return instance; } Meyers Singleton Consequences instance initialized when getInstance() is called the rst time instance ist destroyed automatically (std::atexit()) Order of destruction of static objects is arbitrary! Problematic if static objects are interdependent Dead reference problem Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 16 / 48 The Meyers Singleton Detecting Dead Reference Access // singleton.h class Singleton { // ... as before private: static bool destroyed_; }; // singleton.cpp Singleton::destroyed_ = false; Singleton::~Singleton() { destroyed_ = true; } Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 17 / 48 The Meyers Singleton Detecting Dead Reference Access // singleton.cpp Singleton& Singleton::getInstance() { static Singleton instance; if(destroyed_) throw std::runtime_error( "Singleton: Dead Reference Access"); else return instance; } Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 18 / 48 The Phoenix Singleton Phoenix from the ashes Dead reference access now correctly throws an exception Situation unsatisfactory if dependency cannot be avoided Idea: Re-create the destroyed Singleton after its destruction: Phoenix Singleton a a Alexandrescu, Modern C++ Design, Addison-Wesley, 2001 Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 19 / 48 The Phoenix Singleton The Phoenix Singleton // singleton.cpp Singleton* Singleton::pkill_ = 0; Singleton& Singleton::getInstance() { static Singleton instance; if(destroyed_) { new(&instance) Singleton; // placement new pkill_ = &instance; // init kill pointer std::atexit(kill); // register destruction destroyed_ = false; } return instance; } void Singleton::kill() { pkill_->~Singleton() } Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 20 / 48 The Phoenix Singleton Phoenix Disadvantages If the Singleton keeps state, it is lost after destruction Use of atexit is a low level hack Longevity Patterns More advanced patterns for controlling the lifetime of objects can be found in Alexandrescu, Modern C++ Design, Addison-Wesley, 2001 Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 21 / 48 The Phoenix Singleton Phoenix Disadvantages If the Singleton keeps state, it is lost after destruction Use of atexit is a low level hack Longevity Patterns More advanced patterns for controlling the lifetime of objects can be found in Alexandrescu, Modern C++ Design, Addison-Wesley, 2001 Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 21 / 48 Outline Introduction The Singleton Pattern The Monostate Pattern The Bridge Pattern Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 22 / 48 The Monostate Pattern Singleton Ensures only one class object exists Data is encapsulated in the class object Monostate Data members static and private - class level encapsulation Class objects are stateless - any number of instances may exist Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 23 / 48 The Monostate Pattern cong.h class Config { public: Config(); Color getFavoriteColor() const; /* ... */ private: static bool initialized_; static Color favoriteColor_; /* ... */ }; Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 24 / 48 The Monostate Pattern cong.cpp bool Config::initialized_ = false; Color Config::favoriteColor_; Config::Config() { if(!initialized_) { /* ... initialize from file/registry/etc. ... */ initialized_ = true; } } Color Config::getFavoriteColor() const { return favoriteColor_; }; Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 25 / 48 Monostate vs. Singleton Cong as Singleton Config &conf = Config::getInstance(); // get Config object Color col = conf.getFavoriteColor(); Cong as Monostate Config conf = Config(); // create new Config object Color col = conf.getFavoriteColor(); Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 26 / 48 Monostate vs. Singleton Cong as Singleton Config &conf = Config::getInstance(); // get Config object Color col = conf.getFavoriteColor(); Cong as Monostate Config conf = Config(); // create new Config object Color col = conf.getFavoriteColor(); Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 26 / 48 Monostate vs. Singleton Singleton Meyers Singleton oers initialization and destruction Ensuring single instance is dicult and error-prone Single instance explicit in interface Monostate Does not handle destruction leaks dynamic resources Objects are stateless no copy-construction problem Data sharing invisible in interface (implementation detail) Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 27 / 48 Monostate vs. Singleton Singleton Meyers Singleton oers initialization and destruction Ensuring single instance is dicult and error-prone Single instance explicit in interface Monostate Does not handle destruction leaks dynamic resources Objects are stateless no copy-construction problem Data sharing invisible in interface (implementation detail) Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 27 / 48 Outline Introduction The Singleton Pattern The Monostate Pattern The Bridge Pattern - Pimpl Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 28 / 48 The Bridge Pattern The Problem C++ mixes class interface and implementation (header les) Leads to strong compile time dependencies Long compile times slow down development process The Solution Manually decouple interface and implementation: Pimpl idiom (pointer to implementation) Abstract Interface classes Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 29 / 48 The Bridge Pattern The Problem C++ mixes class interface and implementation (header les) Leads to strong compile time dependencies Long compile times slow down development process The Solution Manually decouple interface and implementation: Pimpl idiom (pointer to implementation) Abstract Interface classes Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 29 / 48 The Bridge Pattern The Problem C++ mixes class interface and implementation (header les) Leads to strong compile time dependencies Long compile times slow down development process The Solution Manually decouple interface and implementation: Pimpl idiom (pointer to implementation) Abstract Interface classes Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 29 / 48 The Bridge Pattern The Problem C++ mixes class interface and implementation (header les) Leads to strong compile time dependencies Long compile times slow down development process The Solution Manually decouple interface and implementation: Pimpl idiom (pointer to implementation) Abstract Interface classes Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 29 / 48 The Bridge Pattern The Problem C++ mixes class interface and implementation (header les) Leads to strong compile time dependencies Long compile times slow down development process The Solution Manually decouple interface and implementation: Pimpl idiom (pointer to implementation) Abstract Interface classes Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 29 / 48 The Bridge Pattern - Pimpl person.h class Person { public: Person(const std::string& name); std::string name() const; private: std::string name_; //implementation detail }; person.cpp Person::Person(const std::string& name) : name_(name) {} std::string Person::name() const { return name_; } Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 30 / 48 The Bridge Pattern - Pimpl person.h class Person { public: Person(const std::string& name); std::string name() const; private: std::string name_; //implementation detail }; person.cpp Person::Person(const std::string& name) : name_(name) {} std::string Person::name() const { return name_; } Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 30 / 48 The Bridge Pattern - Pimpl Pimpl version person.h class PersonImpl; // forward declaration of impl class Person { public: Person(const std::string& name); std::string name() const; private: std::tr1::shared_ptr<PersonImpl> p_; //pointer to impl }; Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 31 / 48 The Bridge Pattern - Pimpl Pimpl version person.cpp Person::Person(const std::string& name) : p_(new PersonImpl(name)) // create impl instance {} std::string Person::name() const { return p_->name(); // delegate call to impl } Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 32 / 48 The Bridge Pattern - Pimpl personimpl.h class PersonImpl { public: PersonImpl(const std::string& name); std::string name() const; private: std::string name_; }; personimpl.cpp PersonImpl::PersonImpl(const std::string& name) : name_(name) {} std::string PersonImpl::name() const { return name_; } Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 33 / 48 The Bridge Pattern - Pimpl personimpl.h class PersonImpl { public: PersonImpl(const std::string& name); std::string name() const; private: std::string name_; }; personimpl.cpp PersonImpl::PersonImpl(const std::string& name) : name_(name) {} std::string PersonImpl::name() const { return name_; } Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 33 / 48 The Bridge Pattern - Pimpl Result person.h has no dependency on personimpl.h (forward declaration) No need to recompile client code if personimpl.h changes Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 34 / 48 The Bridge Pattern - Pimpl Add Write Access void Person::setName(const std::string& name) { p_->setName(name); } void PersonImpl::setName(const std::string& name) { name_ = name; } Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 35 / 48 The Bridge Pattern - Pimpl Person p("Peter"); Person pc(p); cout << "p.name(): " << p.name() << endl; cout << "pc.name(): " << pc.name() << endl; cout << "pc.setName(\"Hans\");" << endl; pc.setName("Hans"); cout << "p.name(): " << p.name() << endl; cout << "pc.name(): " << pc.name() << endl; Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 36 / 48 The Bridge Pattern - Pimpl Result p.name(): Peter pc.name(): Peter pc.setName("Hans"); p.name(): Hans // Oops! pc.name(): Hans Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 37 / 48 The Bridge Pattern - Pimpl Result p.name(): Peter pc.name(): Peter pc.setName("Hans"); p.name(): Hans // Oops! pc.name(): Hans Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 37 / 48 The Bridge Pattern - Pimpl Person p("Peter"); Person pc(p); // (1) What happened? Compiler-generated Copy-Constructor is called (1) p and pc share the same PersonImpl object! Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 38 / 48 The Bridge Pattern - Pimpl Copying behavior Implement Copy-Constructor and copy assignment operator and make sure the PersonImpl object is (deep-)copied or implement copy-on-write. . . Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 39 / 48 The Bridge Pattern - Pimpl Copy-on-Write void Person::makeUnique() { if(!p_.unique()) { std::tr1::shared_ptr<PersonImpl> np( new PersonImpl(*p_)); p_ = np; } } void Person::setName(const std::string& name) { makeUnique(); p_->setName(name); } Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 40 / 48 The Bridge Pattern - Pimpl cout << "p.name(): " << p.name() << endl; cout << "pc.name(): " << pc.name() << endl; cout << "pc.setName(\"Hans\");" << endl; pc.setName("Hans"); cout << "p.name(): " << p.name() << endl; cout << "pc.name(): " << pc.name() << endl; Copy-on-Write Result p.name(): Peter pc.name(): Peter pc.setName("Hans"); p.name(): Peter pc.name(): Hans Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 41 / 48 The Bridge Pattern - Pimpl Drawbacks of Pimpl Performance penalty of impl allocation and memory fragmentation Performance penalty due to pointer dereferencing Copying behavior has to be taken care of Source code bloat Sometimes a back-pointer to the interface object is needed (e.g. for virtual function calls) Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 42 / 48 The Bridge Pattern - Pimpl Drawbacks of Pimpl Performance penalty of impl allocation and memory fragmentation Performance penalty due to pointer dereferencing Copying behavior has to be taken care of Source code bloat Sometimes a back-pointer to the interface object is needed (e.g. for virtual function calls) Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 42 / 48 The Bridge Pattern - Pimpl Drawbacks of Pimpl Performance penalty of impl allocation and memory fragmentation Performance penalty due to pointer dereferencing Copying behavior has to be taken care of Source code bloat Sometimes a back-pointer to the interface object is needed (e.g. for virtual function calls) Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 42 / 48 The Bridge Pattern - Pimpl Drawbacks of Pimpl Performance penalty of impl allocation and memory fragmentation Performance penalty due to pointer dereferencing Copying behavior has to be taken care of Source code bloat Sometimes a back-pointer to the interface object is needed (e.g. for virtual function calls) Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 42 / 48 The Bridge Pattern - Pimpl Drawbacks of Pimpl Performance penalty of impl allocation and memory fragmentation Performance penalty due to pointer dereferencing Copying behavior has to be taken care of Source code bloat Sometimes a back-pointer to the interface object is needed (e.g. for virtual function calls) Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 42 / 48 Outline Introduction The Singleton Pattern The Monostate Pattern The Bridge Pattern - Abstract Interface Classes Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 43 / 48 The Bridge Pattern - Abstract Interface Classes Abstract Interface Class // person.h class Person { public: virtual ~Person(); virtual std::string name() const = 0; // factory function - "virtual constructor" static std::tr1::shared_ptr<Person> create(const std::string& name); }; Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 44 / 48 The Bridge Pattern - Abstract Interface Classes Concrete Class // realperson.h class RealPerson : public Person { public: RealPerson(const std::string& name) :name_(name) {} std::string name() const; private: std::string name_; }; Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 45 / 48 The Bridge Pattern - Abstract Interface Classes person.cpp #include "person.h" #include "realperson.h" std::tr1::shared_ptr<Person> Person::create(const std::string& name) { return std::tr1::shared_ptr<Person>( new RealPerson(name)); } create() may choose between dierent implementations of the Interface Class at run-time. Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 46 / 48 The Bridge Pattern - Abstract Interface Classes Result Clients only depend on person.h Link between Person and RealPerson hidden in person.cpp realperson.h can be changed without needing to recompile client code Multiple concrete classes with dierent implementations No interface to implemenation glue code Cost of Interface Classes All function calls are virtual (performance) Additional virtual function table pointer per object (memory) Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 47 / 48 The Bridge Pattern - Abstract Interface Classes Result Clients only depend on person.h Link between Person and RealPerson hidden in person.cpp realperson.h can be changed without needing to recompile client code Multiple concrete classes with dierent implementations No interface to implemenation glue code Cost of Interface Classes All function calls are virtual (performance) Additional virtual function table pointer per object (memory) Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 47 / 48 The Bridge Pattern - Abstract Interface Classes Result Clients only depend on person.h Link between Person and RealPerson hidden in person.cpp realperson.h can be changed without needing to recompile client code Multiple concrete classes with dierent implementations No interface to implemenation glue code Cost of Interface Classes All function calls are virtual (performance) Additional virtual function table pointer per object (memory) Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 47 / 48 The Bridge Pattern - Abstract Interface Classes Result Clients only depend on person.h Link between Person and RealPerson hidden in person.cpp realperson.h can be changed without needing to recompile client code Multiple concrete classes with dierent implementations No interface to implemenation glue code Cost of Interface Classes All function calls are virtual (performance) Additional virtual function table pointer per object (memory) Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 47 / 48 The Bridge Pattern - Abstract Interface Classes Result Clients only depend on person.h Link between Person and RealPerson hidden in person.cpp realperson.h can be changed without needing to recompile client code Multiple concrete classes with dierent implementations No interface to implemenation glue code Cost of Interface Classes All function calls are virtual (performance) Additional virtual function table pointer per object (memory) Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 47 / 48 The Bridge Pattern - Abstract Interface Classes Result Clients only depend on person.h Link between Person and RealPerson hidden in person.cpp realperson.h can be changed without needing to recompile client code Multiple concrete classes with dierent implementations No interface to implemenation glue code Cost of Interface Classes All function calls are virtual (performance) Additional virtual function table pointer per object (memory) Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 47 / 48 Questions? Georg Altmann (LSS Erlangen) C++ Design Patterns 6/4/2009 48 / 48