8 Replies - 6422 Views - Last Post: 29 June 2011 - 04:05 AM Rate Topic: -----

#1 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Simplifying Clumsy Pointer Syntax

Posted 28 June 2011 - 02:24 AM

In my C++ game engine to access a given object's members I use the following syntax:
((CComp*)glut.get_first_object(obj_comp))->func();
get_first_object(type) is a member function of my wrapper class that returns a CObject*. CObject is a base class from which all the game objects derive. If I want to access a function from a derived class I have to first cast the pointer to the object then use the -> operator.
My question is: how can I get around this clumsy syntax? Ideally I'd like to have something like the following:
glut.get_first_object<CComp>(obj_comp)->func();
However I can't use templates as the function is a class member.

This post has been edited by PlasticineGuy: 29 June 2011 - 12:06 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Simplifying Clumsy Pointer Syntax

#2 sunilchintu2468  Icon User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 37
  • Joined: 29-May 11

Re: Simplifying Clumsy Pointer Syntax

Posted 28 June 2011 - 04:12 AM

I think you can use static_cast try it out

This post has been edited by JackOfAllTrades: 28 June 2011 - 04:58 AM
Reason for edit:: Removed unnecessary quote

Was This Post Helpful? 0
  • +
  • -

#3 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Re: Simplifying Clumsy Pointer Syntax

Posted 28 June 2011 - 04:13 AM

You missed the point. I know I can use reinterpret_cast and static_cast, but it still has the clumsy syntax. I'm after a way to have this functionality without having to typecast pointers in the end user code.
Was This Post Helpful? 0
  • +
  • -

#4 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2153
  • View blog
  • Posts: 3,311
  • Joined: 21-June 11

Re: Simplifying Clumsy Pointer Syntax

Posted 28 June 2011 - 07:17 AM

View PostPlasticineGuy, on 28 June 2011 - 11:24 AM, said:

Ideally I'd like to have something like the following:
glut.get_first_object<CComp>(obj_comp)->func();
However I can't use templates as the function is a class member.


Could you clarify what you mean by that? Function templates can be class members as well.
Was This Post Helpful? 1
  • +
  • -

#5 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Simplifying Clumsy Pointer Syntax

Posted 28 June 2011 - 07:55 AM

Excuse my ignorance here for a second: is glut a class that you control?

if so then you can definetly achieve the syntax you are looking for with a simple template function:
#include <iostream>
#include <map>

using namespace std;

struct baseFoo {
    virtual int doWork() = 0;
};

struct FooA : public baseFoo {
    int doWork() { cout << "FooA instance" << endl; return 1;}
};


struct FooB : public baseFoo {
    int doWork() { cout << "FooB instance" << endl; return 0;}
};


class FooManager {
    map<baseFoo*, int> references;
    typedef map<baseFoo*, int>::iterator iterator;
    public:
    enum FooType {
        FOO_A,
        FOO_B,
    };
    
    template<typename FooType>
    FooType* getNewFoo() {
        FooType* obj = new FooType;
        if (obj != NULL) {
            references[obj]++;
        }
        return obj;
    }
    
    template<typename FooType>
    void returnFoo(FooType* obj) {
        references[obj]--;
        if (references[obj] == 0) {
            delete obj;
            references.erase(obj);
        }        
    }
    
    ~FooManager() {
        for(iterator it = references.begin(); it != references.end(); ++it) {
            if ((*it).second != 0) {
                cout << "Unreturned reference: " << (*it).first << endl;
            };
            delete (*it).first;
        }    
    }
    

};

FooManager memory;

int main() {
    FooA *a = memory.getNewFoo<FooA>();
    FooB *b = memory.getNewFoo<FooB>();
    baseFoo *c = memory.getNewFoo<FooA>();
    
    a->doWork();
    b->doWork();
    c->doWork();
    
    memory.returnFoo(a);
    memory.returnFoo(B)/>; 
    //memory.returnFoo(c); //should get an unreturned reference
    return 0;
}


if not you can use either a template function or a macro to hide the ugly syntax
Was This Post Helpful? 1
  • +
  • -

#6 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 857
  • View blog
  • Posts: 2,343
  • Joined: 20-August 07

Re: Simplifying Clumsy Pointer Syntax

Posted 28 June 2011 - 02:25 PM

View PostPlasticineGuy, on 28 June 2011 - 10:24 AM, said:

In my game engine to access a given object's members I use the following syntax:
((CComp*)glut.get_first_object(obj_comp))->func();
get_first_object(type) is a member function of my wrapper class that returns a CObject*. CObject is a base class from which all the game objects derive.
This sounds like where you're going wrong. Do you actually gain anything from deriving all your classes from CObject? It sounds to me like CObject is obscuring the interfaces which you actually need in order to do anything really useful with your objects. If you are using CObject to cluster together things which would otherwise be logically separated, then I think you're over-generalising, and the result will be a lot of additional complexity in your code.

Is there any reason why your class storing CObject (presumably in a single do-everything container) couldn't separate things out which are logically separate and support different interfaces?
Was This Post Helpful? 0
  • +
  • -

#7 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Re: Simplifying Clumsy Pointer Syntax

Posted 28 June 2011 - 11:35 PM

@Nick, @sepp2k: I thought of that but Visual C++ doesn't seem to like having a templated function inside a non templated class:
// header
template <class T>
T* get_first_object (int ty);
// cpp file
template <class T>
T* get_first_object (int ty)
{
	return reinterpret_cast<T*>(get_first_object(ty));
}
// main.cpp
if (sign(glut.get_first_object<CBall>(obj_ball)->get_vel().x) == 1) {
	// ...
}

1>------ Build started: Project: pong, Configuration: Debug Win32 ------
1>  main.cpp
1>  LINK : C:\Users\\documents\visual studio 2010\Projects\pong\Debug\pong.exe not found or not built by the last incremental link; performing full link
1>main.obj : error LNK2019: unresolved external symbol "public: class CBall * __thiscall CGlutWrapper2D::get_first_object<class CBall>(int)" (??$get_first_object@VCBall@@@CGlutWrapper2D@@QAEPAVCBall@@H@Z) referenced in function "public: virtual void __thiscall CComp::step(void)" (?step@CComp@@UAEXXZ)
1>C:\Users\\documents\visual studio 2010\Projects\pong\Debug\pong.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========



@Bench: It has to be that way because the engine's library needs to run through all the objects during the render routine (these are stored in a std::vector<CObject*>). I'd rather not have to modify the engine every time I make a different project or add a new object to one of my projects.

For instance the same code serves a Pong and a Mario game. The code can't possibly know all the objects the end user might want to use and provide forward declarations and overloads for all.

Realise also that I've never tried making a game engine before so it's certainly possible I'm doing it all wrong.

This post has been edited by PlasticineGuy: 29 June 2011 - 12:04 AM

Was This Post Helpful? 0
  • +
  • -

#8 jimblumberg  Icon User is offline

  • member icon


Reputation: 4278
  • View blog
  • Posts: 13,437
  • Joined: 25-December 09

Re: Simplifying Clumsy Pointer Syntax

Posted 29 June 2011 - 03:56 AM

Quote

I thought of that but Visual C++ doesn't seem to like having a templated function inside a non templated class:


When working with templates, remember that both the definition and implementation must be in the same file. It looks like you have your definition in the header and the implementation in another file. This is incorrect.

Jim
Was This Post Helpful? 2
  • +
  • -

#9 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Re: Simplifying Clumsy Pointer Syntax

Posted 29 June 2011 - 04:05 AM

I had no idea! Thanks Jim.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1