2015-04-29 21 views
5

Ho il seguente scenario:Calling diversi costruttori della classe di base a seconda del valore del parametro di ingresso

A seconda del valore di ingresso al costruttore di una classe Derived ho bisogno di chiamare un altro costruttore di Base classe.

Come ad esempio:

struct Base 
{ 
    Base() : v(0) {} 
    Base(int _v) : v(_v) {} 

    int v; 
}; 

struct Derived 
{ 
    Derived(int v) /* if v == 42 call Base() else call Base(int) */ {} 
}; 

int main() 
{ 
    Derived f2(42); 
    Derived f1(1); 
} 

con il mio attuale conoscenza di C++ credo che questo non è possibile, quindi chiedo alla comunità se sono a conoscenza di alcun hack, o il codice sporco che renderanno questo possibile. Si prega di non lasciare che il semplice int s ti guidi, lo scenario di vita reale è molto più complesso. Sentiti libero di mescolare in magia C++ 11.

Modifica: Inoltre, non voglio utilizzare una funzione "init" che a seconda del valore del parametro inizializza in modo diverso le cose.

+0

Beh, probabilmente si tratta di una codifica hardcoded nella responsabilità dei concstructors. Quindi probabilmente ti piacerebbe usare Factory per ottenere la base inizializzata corretta. – senfen

risposta

7

Questa è davvero una richiesta piuttosto strana, forse dovresti riconsiderare l'approccio generale. Qual è il significato di questo particolare valore 42? Qual è la domanda per cui 42 è la risposta? Forse si dovrebbe avere due pari livello Derived s, o sottoclasse Derived per x==42 caso o per x!=42 caso, ecc O forse 42 proviene da un oggetto diverso tipo ed è possibile utilizzare un costruttore a parte per quel tipo?

Ma se si vuole davvero realizzare ciò che si è chiesto, un possibile approccio è quello di avere due costruttori in qualche modo diversi in Derived e un "costruttore di nomi" (funzione statica) per il routing tra di loro. Qualcosa di simile (non ha controllato per compilability, ma l'idea deve essere chiaro):

struct Derived { 
private: 
    Derived(int x): Base(x) {} 
    Derived(): Base() {} 
public: 
    static Derived ConstructDerived(int x) { 
     if (x==42) return Derived(); 
     else return Derived(x); 
    } 
}; 

// usage 
Derived a = Derived::ConstructDerived(42); 
Derived b = Derived::ConstructDerived(43); 

Per questo sarà necessario anche costruttore di copia, ma si può anche restituire puntatori ecc

Un altro approccio, se il il valore di 42 è fissato in fase di compilazione, è di utilizzare modelli e specializzare il costruttore o anche la classe per un particolare valore di 42.

Un altro approccio che penso dovrebbe funzionare, richiede che la classe di base sia copia o spostata- constructible:

struct Derived { 
    Derived(int x): Base((x == 42)? Base() : Base(x)) {} 
};