Jump to content
  • Advertisement
Sign in to follow this  
AAAP

Can this be done in C++?

This topic is 4667 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

Hi everyone. Say I've got a template which holds a user defined type (probably a class for a game object). And I want to create an interface (using overloaded operators) for the developer to access the copy of the class in the template more easily IE: Object<Player> P1; P1->Draw(); basically, can I have a overload like this that points to a function of a member class of the template class? (sounds awkward to ask not sure if im wording that right). Does this can be done by function pointers? like, for the operator overloading paramers, could put a pointer to the function to be used? If it cant be done its no major problem, there are other ways around it. And if you dont udnerstand me/im wording it badly, please let me know so i can try to post a better explanation of what im trying to do.

Share this post


Link to post
Share on other sites
Advertisement
If I understand you correctly, you can overload operator -> to achieve what you want. For example:


template <class T>
class Object
{
public:
// ... whatever else you want in the interface

T* operator-> () { return &mInstance; }
const T* operator-> () const { return &mInstance; }

private:
T mInstance;
};

Share this post


Link to post
Share on other sites
I don't think I follow. Is Draw() a public method of Player? You can accomplish that with an overloaded -> operator as follows:


template< typename T_ >
class Object
{
public:
T_* operator->(void) { return &mWrapped; }

private:
T_ mWrapped;
};




This would give you indirectly call any public method of T_. Are you looking for a more restrictive mechanism, or something altogether different (as I mentioned above I'm not sure I'm understanding you correctly)?

EDIT:
I was beaten! But I'll expand: what I meant by "more restrictive" was something like, you only want to be able to call a subset of T_'s public methods through Object. For example, Draw() and Update(), but not Destroy(), or something. In that case you could do something like:


template< typename T_ >
class Object
{
public:
void Draw(void) { mWrapped->Draw(); }
void Update(void) { mWrapped->Update(); }

// no implementation of Destroy(), you cannot call T_::Destroy()
private:
T_ mWrapped;
};



Attempting to create Object< T_ > for a T_ that doesn't have the appropriate methods will then fail to compile, providing automatic error checking. I'm not 100% convinced of the utility of this technique, but since you've provided no context...

Share this post


Link to post
Share on other sites
Currently, the functions themselves don't exist exactly, we're still planning this all. Still sort of debating whether we're going to use templates or just simply subclass all our objects.

I'll try to explain:

The template is of course initiated like Object<Type> foo;

Inside the template class is a copy of Type as it were.

We want an operator that can talk to Type directly through foo.

For instance, if the copy of Type is called "blah" in the object, we COULD access members of that class by going foo.blah.member_function();

But we want to be able to skip that and just put foo->member_function(); (or some other operator, doesn't really matter but -> makes sense).

Know what I mean? It's pretty much for convenience, to give it the feel of a class even though its contained inside a template (which allows us to make the overall game procedure simpler)

Edit::

And to D00fus, thanks I'll try that right now, I think that will work.

Share this post


Link to post
Share on other sites
That sounds like the operator-> overload is what you want, then.
Note that d00fus's implementation is better since he provided both const and non-const versions.

Share this post


Link to post
Share on other sites
Yeah jpetrie is right, if you want any restrictions on what parts of the wrapped type's interface you can access then the approach I gave isn't sufficient. Another option if you do eventually want that functionality is to return a proxy object from operator-> that restricts the interface appropriately, but like jpetrie I'm not sure of why you'd want to do this without the context :)

Share this post


Link to post
Share on other sites
Some solutions: (I realize that in the time it's taken me to write these, other solutions will have been submitted..)


The easy solution would be:

template <class T>
class Object {
public:
T m_t;
void Draw() { m_t.Draw(); }
};

class Player {
public:
void Draw() { printf ("Drawing\r\n"); }
}; int i;

...
Object<Player> P1;
P1.Draw();




A variation of the example above would be one using inheritance to ensure our Object and Player classes have the same interface. Deriving Object from IDrawable is optional, of course; I did it simply to ensure Object had the same interface as any IDrawable classes, which neatens it a bit imho.


class IDrawable {
public:
virtual ~IDrawable(){}
virtual void Draw()=0;
};

class Player : public IDrawable {
public:
virtual void Draw() { printf ("Drawing\r\n"); }
};

template <class T>
class Object : public IDrawable {
public:
T m_t;
virtual void Draw() { m_t.Draw(); }
};

...

Object<Player> P1;
P1.Draw();



Yet another option would be to derive your Object class from it's template parameter. Of course, the IDrawable interface is completely optional, but I like it.


class IDrawable {
public:
virtual ~IDrawable() {}
virtual void Draw() = 0;
};

class Player : public IDrawable {
public:
virtual ~Player() {}
virtual void Draw() { printf ("Drawing\r\n"); }
};

template <class T>
class Object : public T {
};

...

Object<Player> P1;
P1.Draw();



If you want to specify the Player function to call in the template, you can do something like this, where we pass the function pointer as part of the template specification:


template <class T, void(T::*DrawFunc)()>
class Object {
public:
T m_t;
void Draw() { (m_t.*DrawFunc)(); }
};

class Player {
public:
void Draw() { printf ("Drawing\r\n"); }
}; int i;

...

Object<Player, Player::Draw> P1;
P1.Draw();




There are probably other solutions, but there are a few.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Hmmm I just want to know what was meant by "restrictions" ? because the private/public rules and what not still apply, probably not protected since no subclassing is actually taking place (or does it apply to templates as well) ?

I just want to know what was meant by restrictions. Currently for testing purposes, the solution by doofus has worked fine.

Share this post


Link to post
Share on other sites
Hi again. I've just realized an issue with this:

if the template instance is a pointer? Then it gets confused and says it can't find the members of the type's class in the template class (because yeah they aren't there). Obviously we will need to have pointer functionality with these object classes...

Is it likely that it's simply getting confused because pointers would always use the -> operator regardless of overloading?

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!