Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>An other option (at least if using MS VC++) is to use virtual inheritance:</p> <pre><code>struct MyInterface { virtual void Method1() = 0; virtual void Method2() = 0; }; class Method1Impl : public virtual MyInterface { virtual void Method1() { _tprintf( _T("Method1\n") ); } }; class Method2Impl : public virtual MyInterface { virtual void Method2() { _tprintf( _T("Method2\n") ); } }; class InterfaceImpl : public virtual MyInterface, private Method1Impl, private Method2Impl { }; void TestWeirdInterfaceImpl() { MyInterface* pItf = new InterfaceImpl(); pItf-&gt;Method1(); pItf-&gt;Method2(); } </code></pre> <p>While this seems to work and satisfy what you are looking for (asside from C4250 warning that you will have to suppress with a #pragma), this wouldn't be my approach. (I believe virtual inheritance is still not something that supported across all compilers, but I could be wrong).</p> <p>I would probably go with containment and once boilerplate code is identifier, wrap it into some kind of macro map (similar to maps in ATL or MFC) that would make it really, really difficult to ever screw it up.</p> <p>So this would be my macro approach:</p> <pre><code>struct MyInterface { virtual float Method1( int x ) = 0; virtual int Method2( float a, float b ) = 0; virtual void Method3( const TCHAR* sz ) = 0; }; class Method1Impl { public: float Method1( int x ) { _tprintf( _T("Method1: %d\n"), x ); return 5.0; } }; class Method2and3Impl { public: int Method2( float a, float b ) { _tprintf( _T("Method2: %f, %f\n"), a, b ); return 666; } void Method3( const TCHAR* sz ) { _tprintf( _T("Method3: %s"), sz ); } }; #define DECLARE_METHOD0( MethodName, Obj, R ) \ virtual R MethodName() { return Obj.MethodName(); } #define DECLARE_METHOD1( MethodName, Obj, R, A1 ) \ virtual R MethodName( A1 a1 ) { return Obj.MethodName( a1 ); } #define DECLARE_METHOD2( MethodName, Obj, R, A1, A2 ) \ virtual R MethodName( A1 a1, A2 a2 ) { return Obj.MethodName( a1, a2 ); } class InterfaceImpl : public MyInterface { public: DECLARE_METHOD1( Method1, m_method1Impl, float, int ); DECLARE_METHOD2( Method2, m_method2and3Impl, int, float, float ); DECLARE_METHOD1( Method3, m_method2and3Impl, void, const TCHAR* ); private: Method1Impl m_method1Impl; Method2and3Impl m_method2and3Impl; }; void TestWeirdInterfaceImpl() { MyInterface* pItf = new InterfaceImpl(); pItf-&gt;Method1( 86 ); pItf-&gt;Method2( 42.0, 24.0 ); pItf-&gt;Method3( _T("hi") ); } </code></pre> <p>Until C++ gods grace us with variadic macros, you'll have to declare one for each number of parameters you have. Also if you used multiple inheritance, potentially you wouldn't need the second "Obj" param, but as I've said before, I'd avoid multiple inheritance if there's another solution, which in this case is one extra param.</p> <p>Yet a third option could be something that authors of <a href="http://rads.stackoverflow.com/amzn/click/020161622X" rel="nofollow">Pragmatic Programmer</a> seem to advocate a lot. If you have a ton of cookie cutter code that you don't want to repeat because, as you pointed out, it introduces human error. Define your own language and write a code generator script (python, perl...) to auto-create the actual code. In this case you could almost point at an interface, and have the script write the text out for you. I haven't tried doing this kind of thing myself, but lately have been wanting to use it somewhere just to see and evaluate the outcome.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload