Domanda

Ho alcune domande su che restituisce un riferimento a una variabile locale da una funzione:

class A {
public:
    A(int xx)
    : x(xx)
    {
        printf("A::A()\n");
    }
};

const A& getA1()
{
    A a(5);
    return a;
}

A& getA2()
{
    A a(5);
    return a;
}

A getA3()
{
    A a(5);
    return a;
}

int main()
{
    const A& newA1 = getA1(); //1
    A& newA2 = getA2(); //2
    A& newA3 = getA3(); //3
}

Le mie domande sono =>

  1. Se l'attuazione di getA1() corretta? Ritengo che sia corretta in quanto è restituire l'indirizzo di una variabile locale o temporaneo.

  2. Quali delle affermazioni in main (1,2,3) porterà ad un comportamento indefinito?

  3. In const A& newA1 = getA1(); ha la garanzia standard che un temporaneo vincolato da un riferimento const non sarà distrutto finché il riferimento esce dall'ambito?

È stato utile?

Soluzione

  

1. È l'implementazione getA1() corretta? Ritengo che sia errato che sta tornando indirizzo della variabile locale o temporaneo.

L'unica versione di getAx() che è corretto nel vostro programma è getA3(). Entrambi gli altri hanno undefined comportamento non importa come li si usa in seguito.

  

2. Quali delle affermazioni in principale (1,2,3) porterà ad un comportamento indefinito?

In un nessun senso di loro. Per 1 e 2 il comportamento non definito come risultato dei corpi delle funzioni. Per l'ultima riga, newA3 dovrebbe essere un errore di compilazione, come non si può associare un temporaneo per un riferimento non const.

  

3. In const A& newA1 = getA1(); fa garanzie standard che temporaneamente vincolato da un const   riferimento non verrebbe distrutto finché il riferimento esce dall'ambito?

No. Quanto segue è un esempio di che:

A const & newConstA3 = getA3 ();

Qui, getA3() restituisce una temporanea e la durata di tale temporanea è ora legato al newConstA3 oggetto. In altre parole il temporanea fino a quando esisterà newConstA3 va fuori del campo di applicazione.

Altri suggerimenti

Q1:. Sì, questo è un problema, vedi risposta a Q2

Q2: 1 e 2 non sono definite in quanto si riferiscono a variabili locali sulla pila di getA1 e getA2. Quelle variabili andare fuori del campo di applicazione e non sono più disponibili e più difettoso possono essere sovrascritti come la pila è in continua evoluzione. getA3 opera dal viene creato e restituito al chiamante una copia del valore di ritorno.

Q3: Nessun tale garanzia esiste per vedere la risposta a Q2

.

Credo che il problema principale è che non si sta tornando provvisori a tutti, si dovrebbe

return A(5);

anziché

A a(5);
return a;

In caso contrario, si sta tornando indirizzo variabile locale, non temporanee. E il temporaneo const di riferimento funziona solo per provvisori.

Credo che la sua spiegato qui: temporaneo const riferimento

Se si compilare questo su VC6 si ottiene questo avvertimento

****** avviso del compilatore (livello 1) C4172 tornando indirizzo della variabile locale o temporaneo Una funzione restituisce l'indirizzo di un oggetto variabile o temporanea locale. Le variabili locali e gli oggetti temporanei vengono distrutti Quando una funzione ritorna, quindi l'indirizzo restituito non è valido. ******

Durante il test per questo problema ho trovato cosa interessante (dato codice sta lavorando in VC6):

 class MyClass
{
 public:
 MyClass()
 {
  objID=++cntr;
 }
MyClass& myFunc()
{
    MyClass obj;
    return obj;
}
 int objID;
 static int cntr;
};

int MyClass::cntr;

main()
{
 MyClass tseadf;
 cout<<(tseadf.myFunc()).objID<<endl;

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top