Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualHodgman

Posted 19 March 2013 - 06:31 AM

In your example, your destructor doesn't need to be virtual because you're not inheriting from this class any more.
Also, your class violates the rule of three / rule of two. If a class has a destructor, then it almost certainly requires a copy constructor and assignment operator (even if they're private and not actually implemented).
 
Another alternative to PIMPL here is to have sub-classes created via the factory pattern, and avoid virtual by casting, e.g.
 
//texture.h
class Texture
{
public:
  static Texture* Create(...);
  static void Destroy( Texture* );
  int GetFoo();
protected:
  Texture() {}
  ~Texture() {} //stop the user from creating a Texture object outside of Create/Destroy
private:
  Texture(const Texture&);
  Texture& operator=(const Texture&); //stop anyone from copying a Texture object
};
 
//texture_gl.cpp
class TextureGL : public Texture
{
public:
  int foo;
...
};
 
//forward on the Texture calls to TextureGL -- a good compiler will optimize these out so the code is perfectly efficient.
Texture* Texture::Create() { return new TextureGL; }
void Texture::Destroy( Texture* t ) { delete (TextureGL*)t; }
int Texture::GetFoo() { return ((TextureGL*)this)->foo; }

#1Hodgman

Posted 19 March 2013 - 06:29 AM

In your example, your destructor doesn't need to be virtual because you're not inheriting from this class any more.

Also, your class violates the rule of three / rule of two. If a class has a destructor, then it almost certainly requires a copy constructor and assignment operator (even if they're private and not actually implemented).

 

Another alternative to PIMPL here is to have sub-classes created via the factory pattern, and avoid virtual by casting, e.g.

//texture.h
class Texture
{
public:
  static Texture* Create(...);
  static void Destroy( Texture* );
  int GetFoo();
protected:
  Texture() {}
  ~Texture() {} //stop people from creating a texture object
};
 
//texture_gl.cpp
class TextureGL : public Texture
{
public:
  int foo;
...
};
 
//forward on the Texture calls to TextureGL -- a good compiler will optimize these out so the code is perfectly efficient.
Texture* Texture::Create() { return new TextureGL; }
void Texture::Destroy( Texture* t ) { delete (TextureGL*)t; }
int Texture::GetFoo() { return ((TextureGL*)this)->foo; }

PARTNERS