Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ struct initialization

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?

like image 755
dk123 Avatar asked Dec 19 '12 11:12

dk123


3 Answers

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)      
}
like image 165
Pubby Avatar answered Sep 29 '22 03:09

Pubby


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. */
like image 22
Bart van Ingen Schenau Avatar answered Sep 29 '22 03:09

Bart van Ingen Schenau


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.

like image 31
yiding Avatar answered Sep 29 '22 01:09

yiding