I've been doing some code redesign lately, and have come across a design issue I can't seem to answer easily myself. Suppose I have a simple OpenGL wrapper class, for example:
class OpenGL : public GraphicsDriver{public: ... virtual void depthMask(GLboolean flag) { glDepthMask(flag); } virtual void begin(GLenum mode) { glBegin(mode); } virtual void end() { glEnd(); } ...};
Then I have a derived class supporting logging:
class OpenGLLogger : public OpenGL{public: ... virtual void depthMask(GLboolean flag) { printf("glDepthMask(%d)\n", flag); OpenGL::depthMask(flag); } virtual void begin(GLenum mode) { printf("glBegin(%d)\n", mode); OpenGL::begin(mode); } virtual void end() { printf("glEnd()\n"); OpenGL::end(); } ...};
And I also have another derived class supporting state caching (this is obviously a very simple example):
class OpenGLCaching : public OpenGL{public: ... virtual void depthMask(GLboolean flag) { mDepthMask = flag; } virtual void begin(GLenum mode) { flushState(); OpenGL::begin(mode); } ...private: void flushState() { OpenGL::depthMask(mDepthMask); ... }};
And so, my two questions:
1) As an end-user, if I was given this code (which is already built in a library or DLL that I cannot modify), is there any easy way for me to utilize the caching ability of the OpenGLCaching class, yet also allow logging through the provided OpenGLLogger class? My guess is "no", since I can't just derive from both classes -- the compiler won't know what virtual function to call in what order.
2) (Assuming #1 is no) As the developer, is there any design pattern I can use that would allow an end-user to be able to perform something like the above example?
Perhaps some of the C++ gurus out there would have a better suggestion. Thanks!