Jump to content
  • Advertisement
Sign in to follow this  
BBB

Multiple Inheritance problem (I think)

This topic is 4832 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Im writing a tutorial for NeHe on how to separate your engine into loadable modules and how to separate generic code that works on both Linux and Windows. When compiling I get this error: g++ -fPIC -Wall -pedantic -ansi glx/renderer_glx.cc -c g++ -fPIC -Wall -pedantic -ansi glx/renderer_glx_factory.cc -c glx/renderer_glx_factory.cc: In function `iRenderer_x11* renderer_x11_factory() ': glx/renderer_glx_factory.cc:5: error: cannot allocate an object of type ` cRenderer_glx' glx/renderer_glx_factory.cc:5: error: because the following virtual functions are abstract: ../renderer.hpp:13: error: virtual bool iRenderer::m_set_resolution(unsigned int, unsigned int) renderer_x11.hpp:34: error: virtual bool iRenderer_x11::m_render_frame() ../renderer.hpp:16: error: virtual void iRenderer::m_add_cube(float, float) make: *** [glx/renderer_glx_factory.o] Error 1 Im using multiple inheritance here and it inherits code from the wrong class. It should inherit from cOpenGL_renderer but instead it inherits from iRenderer_x11 which does nothing. I had the same problem in the Windows version which I solved by randomly messing around with the class declarations :P . My interfaces and classes:
// Generic inteface used in AI, physics modules et.c.:
class iRenderer
 {
  public:
  virtual ~iRenderer() { }
  
  virtual bool m_set_resolution(uint a_width, uint a_height) = 0;
  
  virtual bool m_render_frame(void) = 0;
  virtual void m_add_cube(float a_pos, float a_size) = 0;
  virtual bool m_kill_window(void) = 0;
  
  enum {m_default_screen_width = 1024 };
  enum {m_default_screen_height = 768 };
 }; // end class iRenderer


// X11 interace used when creating window in Linux
class iRenderer_x11 : public iRenderer
 {
  public:
  virtual bool m_pure_virtual(void) { return true; }
  virtual bool m_create_x11_window(bp_x11_window &a_bp_x11_window) = 0;

  virtual bool m_render_frame(void) = 0;

  virtual void m_release(void) { delete this; }

 }; // end class iRenderer_x11 : virtual public iRenderer

typedef iRenderer_x11* x11_renderer_factory_ptr();

// And the one for windows:
class iRenderer_win32 : virtual public iRenderer
 {
  public:
  virtual ~iRenderer_win32() { delete this; }
  
  virtual bool m_create_win32_window(sWin32_window_bp *a_win32_window) = 0;
  virtual bool m_swap_buffers(void) = 0;
  

 }; // end class iRenderer_win32 : public virtual iRenderer

// Then we have our OpenGL classes that does all the actual rendering:
class cOpenGL_renderer : public iRenderer
 {
  public:
  cOpenGL_renderer() { m_rot = 0.0f; }
  virtual bool m_render_frame(void);
  virtual void m_add_cube(float a_pos, float a_size);
  virtual int  m_initGL(void);
  virtual int  m_load_bmp(char *filename, sTextureImage *texture);
  virtual bool m_set_resolution(uint a_width, uint a_height);
  
  protected:
  float m_rot;
 }; // end class cOpenGL_renderer : public virtual cRenderer

// And its here the problem lies:
class cRenderer_glx : public iRenderer_x11, public cOpenGL_renderer
 {
  protected:
  GLXContext m_ctx;
  bp_x11_window *m_x11_window;

  int m_attrListSgl[10];

  int m_attrListDbl[11];

  public:
  cRenderer_glx();
  virtual bool m_pure_virtual(void) { return false; }
  virtual bool m_create_x11_window(bp_x11_window &a_bp_x11_window);
  virtual bool m_kill_window(void);

  virtual void m_release(void) { delete this; }
 }; // end class cRenderer_glx : virtual public cOpenGL_renderer , public iRenderer_x11

// renderer_glx_factory.cc:
#include "renderer_glx.hpp"

extern "C" iRenderer_x11* renderer_x11_factory()
 {
  return new cRenderer_glx;
 } // end extern "C" iRenderer_x11* renderer_x11_factory()


// And finally the windows one:
class cWGL_renderer : virtual public cOpenGL_renderer , public iRenderer_win32
 {
  public:
         
  virtual bool m_create_win32_window(sWin32_window_bp *a_win32_window);
  virtual bool m_swap_buffers(void);
  virtual bool m_kill_window(void);
  
  protected:
  sWin32_window_bp    *m_win32_window;
 }; // end class cWGL_renderer : public virtual cOpenGL_renderer , public virtual iRenderer_win32



Something tells me I need to use RTTI and dynamic_cast and stuff to solve this. I would ofcourse prefer not to since im not doing anything complicated here, I just want it to link from a class which has an implementation.

Share this post


Link to post
Share on other sites
Advertisement
May i suggest spending some time reading this find out the difference between multiple & virtual inheritance, when & where to use them. May i also suggest thinking of an alternative design instead the current one.

Share this post


Link to post
Share on other sites
Interesting.

Consider inheriting iRenderer_win32 and iRenderer_win32 from cOpenGL_renderer.

Kuphryn

Share this post


Link to post
Share on other sites
Interfaces are a decent example for virtual inheritence.

Architecturally, you have combined the Window Manager with the Renderer which is problematic. Consider using seperare classes such as a cRender_ogl, and a cWM_X11 & cWM_Win32. This would match the OGL model.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!