Listing 3
template<class wnd> struct window_creator;
// never derive from this directly;
// derive from generic_wnd instead
class window_base {
window_base(HWND h) : h(h) {}
template<class wnd> friend struct window_creator;
protected:
window_base() {
assert(false); // never construct this directly!
}
private: HWND h;
};
struct generic_wnd : public virtual window_base {};
template<class impl> struct window_creator : public impl {
// trimmed down example, allowing only two arguments
template< class par1, class par2>
window_creator(HWND h, const par1 & p1, const par2 & p2)
: window_base(h), impl(p1,p2) {}
};
template<class impl, class par1, class par2>
shared_ptr<impl> create_wnd(HWND h, const par1 & p1, const par2 & p2) {
// note: window_creator is just a convenience class; it derives
// from impl, and makes sure the right constructors are called
return shared_ptr<impl>( new window_creator<impl>(h, p1, p2));
}
// my window class
struct sample : generic_wnd {
sample( const std::string & arg1, int arg2) {
std::cout << arg1 << arg2 << std::endl;
}
};
int main() {
create_wnd<sample>( (HWND)0x2400, "my sample ", 1); // ok
sample bad( "it won't work", 2); // assertion failed
}