2009-02-06 6 views
7

Sto cambiando una vecchia routine che utilizzava un parametro intero in modo che ora assuma un riferimento const a un oggetto. Speravo che il compilatore mi dicesse da dove viene chiamata la funzione (perché il tipo di parametro è sbagliato), ma l'oggetto ha un costruttore che accetta un intero, quindi piuttosto che fallire, il compilatore crea un oggetto temporaneo, passandolo intero e passa un riferimento a quello alla routine. Esempio di codice:Come posso dire al compilatore di non creare un oggetto temporaneo?

class thing { 
    public: 
    thing(int x) { 
     printf("Creating a thing(%d)\n", x); 
    } 
}; 

class X { 
    public: 
    X(const thing &t) { 
     printf("Creating an X from a thing\n"); 
    } 
}; 


int main(int, char **) { 
    thing a_thing(5); 
    X an_x(6); 
    return 1; 
} 

voglio la linea X an_x(6) a si compila, perché non c'è X costruttore che prende un int. Ma lo fa compilare, e l'output appare come:

Creating a thing(5) 
Creating a thing(6) 
Creating an X from a thing 

Come posso mantenere il costruttore thing(int), ma non consentire l'oggetto temporaneo?

risposta

11

Utilizzare la parola chiave explicit nel costruttore di elementi.

class thing { 
public: 
    explicit thing(int x) { 
     printf("Creating a thing(%d)\n", x); 
    } 
}; 

Ciò impedirà al compilatore di chiamare implicitamente il costruttore di cose quando trova un numero intero.

+0

Vedere questa risposta: http://stackoverflow.com/questions/121162/what-does-the-explicit-keyword-in-c-mean – Skizz

+0

Perfect - Ho scritto codice C++ per circa 15 anni, e ho mai sentito parlare della parola chiave esplicita. Grazie! –

+0

Domanda correlata: puoi usare la parola chiave esplicita su un metodo che non è un costruttore? –

1

La parola chiave funziona perfettamente nel mio esempio, ma in seguito mi sono reso conto che il mio codice reale era in errore su un metodo sovraccaricato, non sul costruttore. (Colpa mia per aver posto una domanda simile, ma non uguale, al mio problema reale.) Come sottolineato da Mark Ransom nei commenti sulla risposta accettata, explicit funziona solo sui costruttori. Ho trovato una soluzione che risolvesse il mio problema, quindi ho pensato di pubblicarlo qui. Nuovo codice di esempio:

class thing { 
    public: 
    thing(int x) { 
     printf("Creating a thing(%d)\n", x); 
    } 
}; 

class X { 
    public: 
    void do_something(const thing &t) { 
     printf("Creating an X from a thing\n"); 
    } 
}; 


int main(int, char **) { 
    thing a_thing(5); 
    X an_x; 
    an_x.do_something(6); 
    return 1; 
} 

Questo codice mostra lo stesso output come il codice originale, ma non posso usare explicit per risolvere il problema. Invece, ho aggiunto un metodo privato che prende un int:

private: 
    void do_something(int x); 

Ora, il compilatore non crea l'oggetto temporaneo, dà un errore, perché sto cercando di chiamare un metodo privato al di fuori della classe.

+0

in C++ 1x, saremo in grado di scrivere void do_something (int x) = delete; funziona già nel tronco gcc svn. –

+0

@Greeme Perrow. L'esplicito dovrebbe funzionare anche nel caso in cui si delinea. Cioè, rendere esplicito il costruttore di cosa comporterà un errore del compilatore. È perché non hai accesso alla classe delle cose per modificarlo? @litb abbiamo iniziato a chiamarlo C++ 1x ora? Mi sono perso il memo? – zdan

+0

@zdan: hai ragione. Stavo pensando a come modificare la classe X e non stavo pensando di modificare la classe delle cose. Questo fa quello di cui ho bisogno. Grazie! –

Problemi correlati