2012-02-15 20 views
19

Voglio rendere un argomento per una delle funzioni membro opzionale. Quando non viene fornito alcun argomento, utilizzerà una variabile membro.Come utilizzare una variabile membro come argomento predefinito in C++?

Tuttavia, quando ho provato a compilarlo mostra "errore: Utilizzo non valido di membro di dati non statici 'oggetto :: initPos'"

Solo per isolare il problema, ho provato inadempiente un tipo int e ha compilato bene. Mi chiedo quale sia il problema con il mio codice e come potrei usare una funzione membro come valore predefinito.

Grazie per il vostro aiuto!

Object.h

class Object 
{ 
    public: 
     ... 
     void MoveTo(double speed, Point position); 

    protected: 
     Point initPos; 
     Point currPos; 

}; 

Object.c

void Object::MoveTo(double speed, Point position = initPos) 
{ 
    currPos = postion; 
} 

Point.h

class Point 
{ 
    ... 

    private: 
     double x; 
     double y; 
     double z; 
}; 
+1

La sua domanda mi ha fatto Spawn questo: http://stackoverflow.com/questions/9286801/valid-expressions-for-default-function-arguments –

risposta

30

Le espressioni di argomento predefinite per una funzione membro possono dipendere solo da cose che sono in ambito di classe o globale. Anche l'argomento predefinito deve essere specificato nella dichiarazione del metodo (ad esempio nel file di intestazione).

Per aggirare questo problema, sono necessari 2 sovraccarichi del metodo MoveTo. Uno che accetta 1 argomento e un altro che accetta 2 argomenti. Il metodo che accetta 1 argomento chiama l'altro metodo, passando il valore che tu consideri come predefinito.

void Object::MoveTo(double speed) 
{ 
    MoveTo(speed, initPos); 
} 

void Object::MoveTo(double speed, Point position) 
{ 
    // Everything is done here. 
} 

Si noti che quando si effettua MoveTo(double) chiamata MoveTo(double, Point), che permette di scrivere l'attuazione di MoveTo solo una volta, rispettando così il principio DRY.

+0

Grazie! So che posso farlo in questo modo. Mi stavo chiedendo se c'è un modo più breve per farlo, come renderlo un argomento predefinito. Ma immagino che questo sarebbe l'unico modo per farlo. – tuzzer

+0

E se invece di una sola discussione facoltativa, ne ho molte di quelle? dire oggetto void :: MoveTo (doppia velocità, posizione del punto = initPos, punto a = m_a, punto b = m_b, punto c = m_c) quindi non dovrò fare molte funzioni ??? – tuzzer

+0

@MatthewChan: Purtroppo sì. Invece di passare molti argomenti, è possibile modificare il progetto in modo che l'utente passi un oggetto.Questo oggetto contiene già valori predefiniti ragionevoli e l'utente cambia solo quelli che devono essere diversi. Se decidi di farlo in questo modo, potresti essere interessato all'idioma del metodo di concatenamento per rendere l'impostazione di più parametri più concisi (http://en.wikipedia.org/wiki/Method_chaining). –

10

valori predefiniti non fanno parte del prototipo, vale a dire che stanno risolto dal chiamante, non dalla funzione stessa. Quindi, in primo luogo, devono essere visibili al chiamante. In secondo luogo, non possono accedere ai membri protetti della classe. (Sono abbastanza sicuro che non puoi nemmeno utilizzare i membri pubblici come predefiniti, ma sono troppo stanco per controllare.)

Per risolvere il problema, utilizzare sovraccarichi concatenati come suggerito in altre risposte.

+0

Grazie. Ho provato a cambiare initPos in pubblico, ma come hai detto, non funzionerà ancora. Quindi è possibile utilizzare solo l'argomento costante come predefinito (come non la funzione membro, qualcosa che puoi digitare) ?? – tuzzer

1

È possibile sovraccaricare il membro funzione del genere:

void Object::MoveTo(double speed, Point position) { 
    .... 
} 

void Object::MoveTo(double speed) { 
    Point position = this->initPos; 

    MoveTo(speed, position); 
} 
+0

sfortunatamente l'unico lavoro che può portare a termine il lavoro, sembra brutto però :( – Argento

Problemi correlati