2010-11-10 32 views
6

sto guardando il codice del modulo:valore di inizializzazione di un membro const riferisco

class foo 
{ 
    public: 
    foo() {} 

    //... 
}; 

class bar 
{ 
    public: 
    bar() : ref() {} 

    private: 
    const foo &ref; 
}; 

l'inizializzazione un riferimento utilizzando una temporanea in questo modo corretto? So che è possibile inizializzare un riferimento const che è una variabile locale con un temporaneo e che così facendo estende la durata del temporaneo, ad es.

const foo &tmp = funcThatReturnsByValue(); //OK 

Tuttavia, una delle risposte alla relativa initialize reference in initialization list suggerisce che v'è una differenza tra, e che l'inizializzazione ref come sopra è un comportamento indefinito "longeva" Riferimenti "di breve durata", e (anche se ref è un riferimento const).

12.2.5 nello standard dice, in parte, "Un vincolo temporaneo a un membro di riferimento nell'inizializzatore di un Ctor di un costruttore persiste finché il costruttore non si chiude." È questo che descrive questa situazione?

+0

È possibile correggere il codice in modo che implichi effettivamente un codice temporaneo? –

+0

ref() non associa riferimento a un'istanza temporanea di foo? Scusa se la mia terminologia è imprecisa ... Sto facendo del mio meglio per capire questo frammento di codice. – user168715

+0

Forse questo commento è senza valore (non conosco il contesto in cui stai guardando questo codice), ma il problema scompare se 'ref' è un puntatore. Il punto è che i riferimenti non possono essere inizializzati in base al valore, ma i puntatori possono (vengono inizializzati a zero). Inoltre, la maggior parte dei compilatori (almeno MSVC) emette un avviso per non essere in grado di generare un operatore di assegnazione predefinito. Come linea guida, ogni volta che vuoi un membro di riferimento, vuoi effettivamente un puntatore ... –

risposta

4

Questo codice è mal formato. Non è possibile inizializzare o valore predefiniti inizializzare un riferimento.

Se in effetti era presente un'espressione all'interno di ref(), allora sì, si applicherebbe 12.2.5 e il temporaneo verrebbe distrutto alla chiusura del costruttore.

+1

Si potrebbe pensare, ma non riesco a ottenere GCC 4.3.4 per farlo davvero. –

1

Credo che quello che si vuole fare è:

bar() : ref(foo()) {} 

ma non ingenuamente pensare che la durata di un temporaneo è esteso fino a quando c'è un riferimento ad esso. No, in realtà non lo è. Quindi, sia const o no, è necessario inizializzare il riferimento con un oggetto normale.

2

Il tuo esempio non sta creando una temporanea - per fare questo è necessario cambiare a:

bar() : ref(foo()) {} 

Ora si sta vincolante il riferimento a una temporanea, e che oggetto temporaneo sarete distrutti alla fine del costruttore. Il tuo riferimento non sarà valido e non è una buona cosa.

Problemi correlati