Jump to content


Accessing Members of Derived Objects


3 replies to this topic

#1 Flamesilver

    New Member

  • Members
  • PipPip
  • 28 posts

Posted 25 March 2011 - 04:06 PM

I'm trying to code a game in C++. I'm having troubles implementing state objects while trying to follow this design framework (amazing article, btw):

[link]http://www.devmaster...oo-game-design/[/link]

From my understanding, every GameEntity & GameForm has a std::map<string, State&> States. Every type of State (i.e. AccelerationRate or something) is a class derived from State, and therefore can be stored in this hashtable via its base pointer/reference (the State portion).

My issue is accessing those State objects. Since I'll be storing a reference to the State base object and not its derived version, how do I access the derived object's members through the base object reference?

Look at this pseudo-code example:

class BaseClass {

  public:

    int baseint;

};


class DerivedClass: BaseClass {

  public:

    int derivedint;

};


void main () {


DerivedClass dc;


BaseClass &BCP = dc;  // reference to the BaseClass portion of dc, which is derived


cout << BCP.derivedint;  // *** THIS DOESN'T WORK, DOES IT?! ***


}



#2 Reedbeta

    DevMaster Staff

  • Administrators
  • 5311 posts
  • LocationSanta Clara, CA

Posted 25 March 2011 - 05:23 PM

Ahh, that's a classic problem in OO design. One approach to solving it is to use virtual methods; if there's a standard set of operations you need to perform on State objects, then you can make each one a virtual method, which has the same signature (parameters and return type) everywhere, but can have a different implementation (function body) in each derived class.

However, virtual methods are not very flexible. For full access to the derived class, you have to provide a way of figuring out what kind of derived class it is, and then cast the pointer to it. (I'll describe this using pointers, but the same thing should be possible with references as they're just syntactic sugar for pointers.)

One way of figuring out what kind of derived class it is would be to create an enum that lists all the possible derived classes and have a field for that in the parent class. Then you can switch based on that field and do the right thing.

enum ClassKind {
    ClassKind_Foo,
    ClassKind_Bar
};

class BaseClass {
public: ClassKind m_classkind;
};

class Foo: public BaseClass {
public: int m_fooInt;
    Foo () { m_classkind = ClassKind_Foo; }
};

class Bar: public BaseClass {
public: float m_barFloat;
    Bar () { m_classkind = ClassKind_Bar; }
};

void DoSomething (BaseClass * pBc) {
    switch (pBc->m_classkind) {
        case ClassKind_Foo: {
            Foo * pFoo = static_cast<Foo *>(pBc);
            // do something with pFoo; you can look at pFoo->m_fooInt, etc.
            break;
        }
        case ClassKind_Bar: {
            Bar * pBar = static_cast<Bar *>(pBc);
            // do something with pBar; you can look at pBar->m_barFloat, etc.
            break;
        }
    }
}

reedbeta.com - developer blog, OpenGL demos, and other projects

#3 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 25 March 2011 - 05:39 PM

Also, I would discourage the use of references in container types, as they're not copy-assignable or default-constructable. For example, operator[] on your map will not work.
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#4 Flamesilver

    New Member

  • Members
  • PipPip
  • 28 posts

Posted 25 March 2011 - 08:32 PM

Thanks for your help yet again!

I will use pointers, yes. That's actually what's in my code right now, anyway. Just figured references are cleaner to write and understand.

Seems like I keep running into these classic problems.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users