Pergunta

Eu tenho algumas perguntas sobre retornar uma referência a uma variável local de uma função:

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
}

As minhas perguntas são =>

  1. é a implementação de getA1() correto? Eu sinto que é incorreta, pois é devolver o endereço de uma variável local ou temporário.

  2. Qual das afirmações em main (1,2,3) vai levar a um comportamento indefinido?

  3. Em const A& newA1 = getA1(); faz a garantia padrão que uma temporária ligada por uma referência const não será destruído até que a referência fica fora do escopo?

Foi útil?

Solução

1. implementação getA1() é correto? Eu sinto que é incorreto como ele está retornando endereço da variável local ou temporária.

A única versão do getAx() que está correto em seu programa é getA3(). Ambos os outros têm um comportamento indefinido, não importa como você usá-los mais tarde.

2. Qual das afirmações em principal (1,2,3) vai levar a um comportamento indefinido?

Em uma nenhum sentido deles. Para 1 e 2 o comportamento indefinido é como um resultado dos corpos das funções. Para a última linha, newA3 deve ser um erro de compilação que você não pode vincular um temporário para uma referência não const.

3. Em const A& newA1 = getA1(); faz garantias padrão que encadernados temporária por um const referência não será destruído até que a referência fica fora do escopo?

No. O seguinte é um exemplo de que:

A const & newConstA3 = getA3 ();

Aqui, getA3() retorna uma temporária e o tempo de vida que temporária está agora ligado ao objeto newConstA3. Em outras palavras, o temporária existirá até newConstA3 sai do escopo.

Outras dicas

Q1:. Sim, este é um problema, ver resposta à Q2

Q2: 1 e 2 são indefinido como eles se referem a variáveis ??locais na pilha de getA1 e getA2. Essas variáveis ??ir fora do escopo e não estão mais disponíveis e pior pode ser substituído como a pilha está em constante mutação. getA3 trabalha desde uma cópia do valor de retorno é criado e retornado ao chamador.

Q3:. Sem tal garantia existe para ver a resposta para Q2

Eu acho que o principal problema é que você não está voltando temporários em tudo, você deve

return A(5);

em vez de

A a(5);
return a;

Caso contrário, você está retornando endereço da variável local, não temporário. E o temporário para referência const só funciona para temporários.

Eu acho que é explicado aqui: temporária para const referência

Se você vai compilar isso em VC6 você vai receber este aviso

****** aviso do compilador (nível 1) C4172 retornando endereço do variável local ou temporária Uma função retorna o endereço de uma variável local ou objecto temporário. As variáveis ??locais e objetos temporários são destruídos quando uma função retorna, assim que o endereço retornado não é válido. ******

Ao testar para este problema que eu encontrei coisa interessante (determinado código está trabalhando em 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;

}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top