Class with method that returns different pointer depending on implementation?

N

nebjy

Hi,
I've got a problem where I want to have an interface to a Graphics
class (though the nature of the class isn't relevant to the problem),
and I want to have a method that returns a pointer to a different
object, depending on the implementation of the Graphics object. I'm
not sure how to do this, whether a typedef would do it or if I need
a template. As an example, I might implement Graphics with the SDL
Library, then the object would be an SDL_Surface, but I was hoping
I could have a method that returned a generic SURFACE thing of my
devising.

Here's some code which I wrote, to try to explain. However it's
verging on pseudocode because I don't know how to go about it.

*****

//interface
class Graphics
{
public:
Graphics();
~Graphics();

//a "made-up" generic SURFACE type
SURFACE getImage(char* filename);
}

Graphics g;

SURFACE *imgTree;

imgTree = g.getImage("myimage.png");

*****

And the implementation would be somewhere, returning an SDL_Surface
as a SURFACE, then I might have a

typdef SURFACE SDL_surface

somewhere? I don't know, I'm a bit lost, and the code above is probably
completely wrong, so you can take that as given when replying!
There'd only ever be one type of Graphics class at any time, I wouldn't
mix types. The main reason for the abstraction is so that

Any tips would be much appreciated.
 
V

Victor Bazarov

nebjy said:
I've got a problem where I want to have an interface to a Graphics
class (though the nature of the class isn't relevant to the problem),
and I want to have a method that returns a pointer to a different
object, depending on the implementation of the Graphics object. I'm
not sure how to do this, whether a typedef would do it or if I need
a template. As an example, I might implement Graphics with the SDL
Library, then the object would be an SDL_Surface, but I was hoping
I could have a method that returned a generic SURFACE thing of my
devising.

Here's some code which I wrote, to try to explain. However it's
verging on pseudocode because I don't know how to go about it.

*****

//interface
class Graphics
{
public:
Graphics();
~Graphics();

//a "made-up" generic SURFACE type
SURFACE getImage(char* filename);
}

Graphics g;

SURFACE *imgTree;

imgTree = g.getImage("myimage.png");

*****

And the implementation would be somewhere, returning an SDL_Surface
as a SURFACE, then I might have a

typdef SURFACE SDL_surface

somewhere? I don't know, I'm a bit lost, and the code above is probably
completely wrong, so you can take that as given when replying!
There'd only ever be one type of Graphics class at any time, I wouldn't
mix types. The main reason for the abstraction is so that

Any tips would be much appreciated.

The usual way to do this is by use of _polymorphism_. You create your
'SURFACE' type, and any other surface you can think of should inherit
that type:

class SURFACE
{
// declarations that represent interface, usually abstract one
};
....
class Graphics
{
...
SURFACE* getImage(...
};
....
class SDL_surface : public SURFACE
{
};

Get a decent book that describes the use of inheritance and polymorphism
in C++, I recommend "Advanced C++" by James Coplien (although some may
consider it a bit old). Don't get discouraged by strange words and new
terms, they just make it look convoluted, in reality it's pretty straight-
forward and once you get the hang of it, it's easy and basically becomes
natural to an OO programmer.

Victor
 
N

nebjy

Victor said:
The usual way to do this is by use of _polymorphism_. You create your
'SURFACE' type, and any other surface you can think of should inherit
that type:
...
class Graphics
{
...
SURFACE* getImage(...
};
...
class SDL_surface : public SURFACE
{
};

I understand you and I get inheritence generally, but I don't think it's
a solution in this case.

The thing is that SDL_Surface is already implemented in SDL, and a
different implementation (say, with openGL) almost certainly wouldn't
share the same methods and data. As a result I can't create a common
SURFACE interface, and I can't define SDL_surface myself. I wouldn't
actually want to access
data or methods of the SURFACE, I'd just want a direct pointer to it
so I could then pass it to, say, a drawImage(SURFACE s) method to
draw it on the screen or something.

I guess I can just mess around with a typedef and hope for the best :)
I'm not too worried about adjusting a couple of lines and recompiling
if I need to change the implementation to something different.

Thanks for the reply.
 
V

Victor Bazarov

nebjy said:
I understand you and I get inheritence generally, but I don't think it's
a solution in this case.

The thing is that SDL_Surface is already implemented in SDL, and a
different implementation (say, with openGL) almost certainly wouldn't
share the same methods and data. As a result I can't create a common
SURFACE interface, and I can't define SDL_surface myself. I wouldn't
actually want to access
data or methods of the SURFACE, I'd just want a direct pointer to it
so I could then pass it to, say, a drawImage(SURFACE s) method to
draw it on the screen or something.

Then what you're asking about is a wrapper (or wrappers) of those
things. You still can make it generic and have derived classes
implement (contain) other (predefined) classes:

class SURFACE_wrapper {
public:
virtual void blah() = 0;
};

class SDL_surface_wrapper : public SURFACE_wrapper {
SDL_surface thing;
public:
void blah();
};
I guess I can just mess around with a typedef and hope for the best :)

Whatever suits you.
I'm not too worried about adjusting a couple of lines and recompiling
if I need to change the implementation to something different.

That's up to you, of course.

Good luck!

V
 
N

nebjy

Victor said:
Then what you're asking about is a wrapper (or wrappers) of those
things. You still can make it generic and have derived classes
implement (contain) other (predefined) classes:

That looks promising, I may give that a go, thanks!

Nick
 
N

nebjy

Victor Bazarov wrote
Then what you're asking about is a wrapper (or wrappers) of those
things. You still can make it generic and have derived classes
implement (contain) other (predefined) classes:

class SURFACE_wrapper {
public:
virtual void blah() = 0;
};

class SDL_surface_wrapper : public SURFACE_wrapper {
SDL_surface thing;
public:
void blah();
};

Oh, just one question. What does it mean to say virtual void blah() = 0?
In particular, the "= 0" part. I've never seen an assignment on a
method declaration.
 
R

red floyd

nebjy said:
Victor Bazarov wrote


Oh, just one question. What does it mean to say virtual void blah() = 0?
In particular, the "= 0" part. I've never seen an assignment on a
method declaration.

the "= 0" part indicates a pure virtual function. That is,
SURFACE_wrapper is an abstract class that cannot be instantiated
directly, but is intended as an interface.
 
N

nebjy

red said:
the "= 0" part indicates a pure virtual function. That is,
SURFACE_wrapper is an abstract class that cannot be instantiated
directly, but is intended as an interface.

Ah okay, thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top