2012-12-19 23 views
8

Poniżej skrócona wersja mojego klasy Sprite:C inicjalizacji ++ struct

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

Chciałbym utworzyć obiekt SpriteState poprzez funkcję składową, która wygląda mniej więcej wzdłuż linii z następujących powodów:

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; } 

pojawia się następujący błąd:

a nonstatic member reference must be relative to a specific object

podstawową ideą klasą sama ma przechowuj różne stany duszka, gdy się zmieniają, aby w razie potrzeby móc łatwo odzyskać do poprzedniego stanu.

Jednak w większości przypadków Sprite jest aktualizowany tylko o nowe wartości pozycji, podczas gdy szerokość, wysokość, obrót i skalowanie pozostają prawie takie same - co oznacza, że ​​zmieniam tylko wartość pozycji podczas pojawiania się i zapisywania ponownie odniesień z ostatni stan zapisany dla innych wartości.

Chciałbym więc móc ustawić wartości domyślne dla funkcji, tak aby nie musiałem pracowicie pisać tych samych wartości wielokrotnie.

Jakieś ewentualne pomysły na wdrożenie?

+1

int szerokość = '=' stateVector.rbegin() -> second.width? – billz

Odpowiedz

1

Powinieneś zrobić kopię SpriteState, a następnie zmodyfikować go:

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

Każdy struct i klasy mają domyślnie konstruktora kopia następującą postać:

ClassName(const ClassName&); 

który domyślnie kopiuje dane w klasie/strukturze.

+0

Wybrałem to jako odpowiedź na jego zwięzłość. Być może nieco poza zakresem OOP, ale wolałbym, aby mój kod był prosty. Dzięki! – dk123

2

przeciążeniowe go:

SpriteState newSpriteState(Vector3 position) 
{ 
    return newSpriteState(
      position, 
      stateVector.rbegin()->second.width, 
      stateVector.rbegin()->second.height, 
      stateVector.rbegin()->second.rotation, 
      stateVector.rbegin()->second.scaling)  
} 
2

argumenty domyślne są oceniane w kontekście rozmówcy, więc jeśli chcesz mieć dostęp do członka klasy, aby uzyskać wartość „default”, nie można korzystać z domyślnego argumenty.

Z drugiej strony, można użyć przeciążenie, aby uzyskać ten sam efekt:

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. */ 
+0

To zdecydowanie bardziej precyzyjne podejście przy wdrażaniu tego. Ostatecznie wybrałem odpowiedź yidinga, ponieważ jest zwięzła. Dziękuję za odpowiedź - na pewno odwołam się do tego przy kolejnych próbach podobnych zadań! – dk123

1

funkcja Użytkownik nie można nazwać członków klasy. Można archiwizować je, wykonując:

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

Następnie należy wywołać tę funkcję w innym member function:

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