Skip to main content
gamedev.net
🔒 Locked 🤖 Godot

Subclasses, pointers and Type Casting (C++)

Started by SymLinked 3 replies 1k views
Original Post
SymLinked
SymLinked
Hello, This issue has got me stuck for really long and I feel like giving up. I have a BaseObject class which is meant to be simple and light, and other classes derive from this one. For simplicity: The subclasses are Human, Alien and Car. I have implemented mounting of Humans to Cars.

// Car.cpp
Human* mountList; // Humans mounted to this object.

// Human.cpp
Car* mountParent; // The car which this human is mounted to.

// Human.cpp (Pseudo Code)
function Human::updateMove( move )
{
    if ( isMounted() )
    {
        // We are mounted, follow the parent.
        pos = mountParent -> getMountObjectPosition();
        setPosition ( pos );
    }
    else
    {
        setPosition ( move );
    }
}
This works great for Humans. The problem is, I cannot mount Aliens because the list expects Human pointers. I tried using BaseObject instead in the list, but BaseObject does not have the function getMountObjectPosition() which I am calling above and I would have to move it, negating the 'simpleness' of the base class. I guess I could static_cast from BaseObject to Human/Alien, but would that be wise in a function which is called every 32 ms, for *each* object? Perhaps there is no performance overhead with static_cast, unlike dynamic_cast? Any help will be greatly appreciated! If we can reach a solution I am willing to send $20 as a thank you via PayPal.
ToohrVyk
ToohrVyk
Two methods are possible:

1° Create a base class that has the getMountObjectPosition method and inherits from BaseObject, and inherit Alien and Human from it. Store a list of this base class inside the car.

2° Create a list of Alien and a list of Human inside each Car, and get objects from the appropriate list.
SymLinked
SymLinked
Thanks for your reply ToohrVyk. I appreciate it.

Quote:
Original post by ToohrVyk
1° Create a base class that has the getMountObjectPosition method and inherits from BaseObject, and inherit Alien and Human from it. Store a list of this base class inside the car.


Adding an additional mountObject class to derive from does not sound very practical to me in that for each function like this it would start to add upp pretty quickly.

Quote:
Original post by ToohrVyk
2° Create a list of Alien and a list of Human inside each Car, and get objects from the appropriate list.


This is something I considered, though it too would add upp quickly for each class that needs to be mounted. I also have to iterate trough these lists when checking if something is mounted, seems like so much overhead.

I was assuming there would be a way to keep different pointer types in one vector, or a way to convert types without performance impact - but obviously that is my inability to program rather than a limit ;)
ToohrVyk
ToohrVyk
Quote:
Original post by SymLinked
Adding an additional mountObject class to derive from does not sound very practical to me in that for each function like this it would start to add upp pretty quickly.


You probably won't get anything more practical that this. You're looking for a way to tell the compiler that Alien and Human are used in the same way for this action, and a shared base class with the appropriate behavior is about the easiest and shortest way you can do this.

Quote:
Original post by ToohrVyk
This is something I considered, though it too would add upp quickly for each class that needs to be mounted. I also have to iterate trough these lists when checking if something is mounted, seems like so much overhead.

I was assuming there would be a way to keep different pointer types in one vector, or a way to convert types without performance impact - but obviously that is my inability to program rather than a limit ;)


A vector can contain pointers to different derived classes, stored as base class pointers. You can either get a performance hit by keeping type information (generally with the default C++ RTTI) that allows you to retrieve the correct type, or group shared methods in a base class.
daerid
daerid
Try this:

class BaseObject{// stuff};class MountableObject;class MountedObject;class MountableObject{  // stuff specific to mountable objects  std::list<MountedObject*> m_mountedObjects;};class MountedObject{  // stuff specific to mounted objects  MountableObject* m_mountParent;  void UpdateMove( move )  {    if( IsMounted() )    {      pos = m_mountParent->getMountedObjectPosition();      setPosition( pos );    }    else      setPosition( move );  }};class Human : public BaseObject, public MountedObject{};class Alien : public BaseObject, public MountedObject{};class Car : public BaseObject, public MountableObject{ };


That's how I'd do it, except with Interfaces and subclassing humans and aliens from some sort of BasePlayer class.
daerid@gmail.com

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.