So to clarify my question... each pattern in infamous GoF book - Design Patterns Elements of Reusable Object-Oriented Software - has its code samples in C++.
A
They are a little out-dated, yes. But part of the point of those books is that these patterns are useful in several different languages and with several different styles. So while the code is a little old in the tooth, the ideas behind it aren't, and those ideas are what's important in those books.
I would like to see some pattern implementations that took advantage of meta-programming techniques. I strongly suspect some patterns, such as Bridge, Adapter and possibly Facade are much less tedious to implement using meta-programming. From the other answer, and reading the description, it looks like Modern C++ Design: Generic Programming and Design Patterns Applied might be a good book for this sort of thing. I can't personally vouch for it though.
Other than the possible use of generic programming and template techniques, the main differences are that bare pointers are a rare thing in C++ nowadays. There are effective smart pointer types that should usually be used instead because they handle a lot of the resource management issues for you. Frankly, unless you know really well what you are doing, I would not recommend attempting a generic programming based design anyway.
Here are some examples of which sorts of smart pointers to use in various contexts. These examples assume that you have a C++ that includes the TR1 (Technical Report 1) extensions:
When you have a pointer to something that is wholly owned by the object pointing to it, use ::std::auto_ptr
(or ::std::unique_ptr
in C++1x). Keep in mind that ::std::auto_ptr
cannot be stored in STL containers, but ::std::unique_ptr
does not have this problem. Examples might be the Component pattern (as long as no two sub-components were shared), the Facade pattern, and the Adapter pattern. Also, the Factory pattern should likely be producing ::std::auto_ptr
s (or ::std::unique_ptr
s in C++1x) unless there is a really good reason to be producing ::std::shared_ptr
s.
When you have a pointer to something that has shared ownership, used ::std::tr1::shared_ptr
. For example, the Flyweight pattern. Also, in some cases, the Component pattern may have this property as well. It may also be useful in Bridge pattern.
When you have a pointer to something that to something that you do not logically own, then a ::std::tr1::weak_ptr
is the way to go. Keep in mind that if you use ::std::tr1::weak_ptr
you should also use ::std::tr1::shared_ptr
for all the objects that do logically own (or share ownership) of the pointed to item. An example for this is the Observer pattern.