Jump to content
  • Advertisement
Sign in to follow this  
polaris2013

virtual static (C++)

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

This is a rather unusual question so let me set it up first: I have a class CActor from which CMonster and CPlayer are both derived. One of the members of the Actor class is the inventory. Monsters and Players have different maximum inventory sizes, however each monster has the same maximum inventory size and trivially each player has the same maximum inventory size (only 1 player). Some of the shared Actor functions need to access the maximum inventory size, so the best way I could think of to handle that was to make a pure virtual function that was defined in both CMonster and CPlayer to return their respective maximum inventory sizes like so:
//CActor::
virtual inline unsigned int MaxInventorySize() = 0;

//CPlayer::
inline unsigned int MaxInventorySize(){ return 60; }

//CMonster::
inline unsigned int MaxInventorySize(){ return 4; }
However I have no run into a situation where it would be useful call this function without an object, specifially:
CMonster::MaxInventorySize();
Unfortunately virtual and static do not play together, so I cannot do this. I'm wondering what would be the best solution to this. I ran into this problem last night and have thought about it some since then but haven't recognized any simple solution yet so I figured this is the type of question someone else can probably answer in 3 seconds so I should quit thinking about it and just ask someone instead.

Share this post


Link to post
Share on other sites
Advertisement

struct Player
{
static std::size_t const MaxInventorySize = 60;
};

struct Monster
{
static std::size_t const MaxInventorySize = 4;
};

Share this post


Link to post
Share on other sites
Or, if you really do have an object that you're calling it on, and actually want runtime 'virtual' behavior:


struct Actor
{
virtual std::size_t MaxInventorySize() const = 0;
};

struct Player : Actor
{
virtual std::size_t MaxInventorySize() const { return 60; }
};

struct Monster : Actor
{
virtual std::size_t MaxInventorySize() const { return 4; }
};

Share this post


Link to post
Share on other sites
Ha, thank you RDragon I knew this was something that someone else could solve instantly! The second solution was just what I needed!

I must admit, I don't fully understand what the const keyword does. I see a lot of other people's code where they put const in places I never thought of and it works. The general rule (I think) is the const modifies the thing to the left of it so this is somehow making the function constant, like static would, except with a different keyword? Am I correct in my understanding of your solution.

I mean, I guess I don't have to understand the solution as long as it works, but it would be appreciated. THANK YOU! :)

------------------

EDIT #1:
WAIT A SECOND, I misspoke above. I just noticed that I had commented out the part where I called CMonster::MaxInventorySize() and when I uncommented it, the call still gives me a compiler error that the function is not static and that it is an illegal call.

So I still do not have a solution.

EDIT #2: (reply to below comment from RDragon)
The first solution does not work because the class CActor cannot access the maximum inventory size. Although it is an abstract class, there is still shared code between CMonster and CPlayer that rely on the max inventory size, for example whether or not another item can be picked up. Therefore the problem is this:

1) CPlayer has a static maximum inventory size
2) CMonster has a static maximum inventory size
3) CActor, which is the parent to both of these classes, must be able to access the correct maximum inventory size
4) The maximum inventory size of the monster must be accessible without having an object instantiated.

Share this post


Link to post
Share on other sites
Well the 'second' solution is just regular old virtual functions, so you will need an object of either type Player or Monster to call it on.

But if you're in the situation you mentioned in your post where you are typing
"CMonster::MaxInventorySize();"

then you should prefer the 1st solution.



A const member function can be called on a const object of that type. In other words, on a const object, you can only call its const member functions.

Share this post


Link to post
Share on other sites
C&P of my above edits: (I realized you probably wouldn't realize I had made those edits unless I added a reply to the topic)

----------------------------------------

WAIT A SECOND, I misspoke above. I just noticed that I had commented out the part where I called CMonster::MaxInventorySize() and when I uncommented it, the call still gives me a compiler error that the function is not static and that it is an illegal call.

So I still do not have a solution.

The first solution does not work because the class CActor cannot access the maximum inventory size. Although it is an abstract class, there is still shared code between CMonster and CPlayer that rely on the max inventory size, for example whether or not another item can be picked up. Therefore the problem is this:

1) CPlayer has a static maximum inventory size
2) CMonster has a static maximum inventory size
3) CActor, which is the parent to both of these classes, must be able to access the correct maximum inventory size
4) The maximum inventory size of the monster must be accessible without having an object instantiated.

Share this post


Link to post
Share on other sites

class InventorySizeInterface {
public:
virtual ~InventorySizeInterface () {};
virtual int GetInventorySize() const = 0;
};

template<int size>
class HasInventorySize:
public virtual InventorySizeInterface
{
public:
virtual ~HasInventorySize() {};
typedef enum {InventorySize = size};
virtual int GetInventorySize() const {return InventorySize;}
};

class Actor:
public virtual InventorySizeInterface
{
// ...
};

class Monster:
public virtual Actor,
public virtual HasInventorySize<4>
{
// ...
};

class Player:
public virtual Actor,
public virtual HasInventorySize<60>
{
// ...
};





How is that:

Actor* a = new Player();
int size = a->GetInventorySize(); // returns 60, virtually
int p_size = Player::InventorySize; // compile time constant equal to 60

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!