8

The following is an abridged version of my Sprite class:

class Sprite
{
    struct SpriteState {
        Vector3 position;
        int width, height;
        double rotation, scaling;
    };
    std::map<int, SpriteState> stateVector;
}

I'd like to create a SpriteState object through a member function that looks something along the lines of the following:

SpriteState newSpriteState(
        Vector3 position = stateVector.rbegin()->second.position, 
        int width = = stateVector.rbegin()->second.width, 
        int height = = stateVector.rbegin()->second.height, 
        double rotation = stateVector.rbegin()->second.rotation, 
        double scaling = stateVector.rbegin()->second.scaling)
    { SpriteState a; a.position = position; a.width = width; a.height = height; a.rotation = rotation; a.scaling = scaling; return a; }

I get the following error:

a nonstatic member reference must be relative to a specific object

The basic idea behind the class itself is to store the various states of the sprite as it changes so that I can easily recover to a previous state if needed.

However, in most cases the Sprite is only updated with new position values while width, height, rotation, and scaling stays pretty much the same - which means I only change the position value while popping up and saving again references from the last state saved for the other values.

I'd hence like to be able to set default values for the function so that I don't have to laboriously write the same values repeatedly.

Any possible ideas on implementation?

1
  • 1
    int width = = stateVector.rbegin()->second.width ? Commented Dec 19, 2012 at 11:11

4 Answers 4

2

Overload it:

SpriteState newSpriteState(Vector3 position)
{
    return newSpriteState(
            position,
            stateVector.rbegin()->second.width, 
            stateVector.rbegin()->second.height, 
            stateVector.rbegin()->second.rotation, 
            stateVector.rbegin()->second.scaling)      
}
Sign up to request clarification or add additional context in comments.

Comments

2

Default arguments are evaluated in the context of the caller, so if you need to access a member of your class to get the 'default' value, you can't use default arguments.

On the other hand, you can use overloading to get the same effect:

SpriteState newSpriteState(
    Vector3 position,
    int width,
    int height,
    double rotation,
    double scaling)
{ 
    SpriteState a; 
    a.position = position; 
    a.width = width; 
    a.height = height; 
    a.rotation = rotation; 
    a.scaling = scaling; 
    return a; 
}

SpriteState newSpriteState(
    Vector3 position)
{
    return newSpriteState(position,
                          stateVector.rbegin()->second.width, 
                          stateVector.rbegin()->second.height, 
                          stateVector.rbegin()->second.rotation, 
                          stateVector.rbegin()->second.scaling);
}
/* ... And similar for additional non-default values. */

1 Comment

This would definitely be the more exact approach in implementing this. I eventually chose yiding's answer though for it's brevity. Thanks for the reply - I'll definitely be referencing this on future attempts at similar tasks!
1

You should make a copy of the SpriteState, and then modify it:

SpriteState newSpriteState(stateVector.rbegin()->second);
newSpriteState.width = someNewWidth;
return newSpriteState;

Every struct and class have by default a copy constructor of the following form:

ClassName(const ClassName&);

Which by default copies the data in the class/struct.

1 Comment

I've selected this as the answer for its brevity. Perhaps slightly out of the scope of OOP, but I'd rather keep my code simple. Thanks!
1

Member function can't call class members. You could archive it by doing:

SpriteState newSpriteState(SpriteState sprite_state)        
{ 
  SpriteState a; 
  a.position = position; 
  a.width = width; 
  a.height = height; 
  a.rotation = rotation; 
  a.scaling = scaling; 
  return a; 
}

Then you call this function in another member function:

newSpriteState(stateVector.rbegin()->second);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.