Pergunta

Estou passando um valor para copiar o construtor como referência, mas um loop infinito está sendo invocado.

Aqui está minha aula:

class Vector2f{
private:
    GLfloat x;
    GLfloat y;

public:
    Vector2f();
    Vector2f(const GLfloat _x, const GLfloat _y);
    Vector2f(const Vector2f &_vector);

    ~Vector2f();
};

Aqui está a implementação de métodos:

Vector2f::Vector2f():
        x( 0.0f ),
        y( 0.0f )
{
    DebugLog("Vector2f constructor");
}

Vector2f::Vector2f(const GLfloat _x, const GLfloat _y):
        x( _x ),
        y( _y )
{
    DebugLog("Vector2f constructor(%f, %f)", _x, _y);
}


Vector2f::Vector2f(const Vector2f &_vector):
        x( _vector.getX() ),
        y( _vector.getY() )
{
    DebugLog("Vector2f copy constructor");
}

Vector2f::~Vector2f()
{

}

Veja como eu acesso a aula:

Vector2f tempVector1 = Vector2f(0.0f, 0.0f);
DebugLog("tempVector1 initialized");

Vector2f tempVector2;
tempVector2 = Vector2f(0.0f, 0.0f);
DebugLog("tempVector2 initialized");

Os resultados que obtive são:

Vector2f constructor(0.000000, 0.000000)
tempVector1 initialized
Vector2f constructor
Vector2f constructor(0.000000, 0.000000)
Vector2f copy constructor
Vector2f copy constructor
Vector2f copy constructor
...

O loop infinito ocorre ao tentar inicializar o objeto criado anteriormente. Se eu tentar copiar o tempvetor1 no tempvetor 2, ocorre um loop infinito:

Vector2f tempVector2;
tempVector2 = Vector2f(tempVector1);

Por que isso acontece e como posso impedir que ele entre em um loop infinito?

Agradeço antecipadamente.

Foi útil?

Solução

Eu acho que o problema está no seu operador de tarefas. Como é o operador =?

Parece que o operador = está se chamando de alguma maneira. É possível que o snippet de código seja retirado do corpo do operador = por si só?

Se for, a solução é alterar o código (Operador interno =), de modo que ele use o cTOR de cópia. A forma canônica é a seguinte:

Vector2f temp = Vector2f(arg);
swap(*this, temp)   // You need to implement a swap method
return *this; 

(Ver C ++ excepcional por Herb Sutter para mais detalhes)

Outras dicas

Está linha:

tempVector2 = Vector2f(tempVector1);

invocaria operador = não o construtor de cópias. Você está definindo um operador = que está fazendo algo maluco?

Além disso, seu código funcionou bem para mim com o G ++ 4.3.2 no Linux e G ++ 4.2.1 no Mac (depois que eu defini o getX, gety, depurto convertido para printf e usei flutuação em vez de glfloat).

No segundo caso, você está realizando tarefas, não a construção. Você não definiu sua própria versão do Operador de Assinatura de Copiar, o que significa que o compilador fornecerá um para você. O operador de assinatura de cópia fornecido pelo compilador será declarado implicitamente como

Vector2f& operator =(const Vector2f& rhs);

Observe que o único parâmetro deste operador possui um tipo de referência para continuar.

No seu código, você está insistindo em fornecer um Rvalue temporário objeto do tipo Vector2f no lado direito da tarefa.

tempVector2 = Vector2f(0.0f, 0.0f);

Isso significa que o parâmetro de referência do operator = é inicializado com um Rvalue temporário do tipo de classe. De acordo com a especificação do idioma (8.5.3/5), o compilador pode copiar esse objeto temporário quantas vezes quiser antes de anexar a referência. Eventualmente, ele deve parar de copiar e finalmente ligar para o operador. Normalmente, o compilador não enlouquece com a cópia (a maioria deles não faz cópia), no entanto, no seu caso, esse parece ser o problema. Por alguma razão, seu compilador é trancado em um loop infinito de cópia, nunca parando. Não sei o que está causando isso. Pode ser um bug no compilador.

Observe que mesmo no

tempVector2 = Vector2f(tempVector1);  

Você ainda está fornecendo o lado direito na forma de um Rvalue temporário. O rvalue é o resultado do elenco explícito para Vector2f Você por algum motivo colocou lá. Eu não tenho ideia de por que você fez isso. Se o problema está realmente no compilador (e não no código que você não está nos mostrando), tenho certeza de que, se você fizer apenas

tempVector2 = tempVector1;  

A tarefa será realizada sem problemas. Na verdade, é assim que você pode contornar o problema se for um bug no compilador: pare de usar temporários como argumentos para copiar constitui-se e operador de assinatura de copiar.

Execute -o sob o IDE. Quando estiver no loop, pressione o botão "Pausa". Você verá exatamente qual é o problema. Aqui está o porquê.

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