Pergunta

Estou escrevendo uma biblioteca de matemática como um exercício prático.Encontrei alguns problemas ao sobrecarregar o operador =.Quando depurei, percebi que a chamada para vertex1 = vertex2 chama o construtor de cópia.

No arquivo de cabeçalho eu tenho:

//constructors
vector3();
vector3( vector3 &v );
vector3(float ix, float iy, float iz);

//operator overloading
vector3 operator =(vector3 p);
....

No arquivo fonte eu implementei:

vector3 vector3::operator =(vector3 p)
{
    vector3 v3;
    v3.x = p.x;
    v3.y = p.y;
    v3.z = p.z;
    return v3;
}

Mais tarde, tenho um método de produto cruzado e quero usá-lo da seguinte forma:

vector3 v3;
v3 = v1.crossProduct(v2);

A mensagem de erro é:erro:Nenhuma função de correspondência para Call to `Vector3 :: Vector3 (Vector3) ', mas não quero chamar o construtor de cópias.

Foi útil?

Solução

Existem erros no seu código.Seu construtor de cópia deve levar um const&.A referência evitará fazer uma cópia (o que você não conseguiria fazer sendo o construtor da cópia), e deve ser const já que você não está modificando:

vector3(const vector3&);

Variáveis ​​temporárias podem ser vinculadas a const&, mas não pode estar vinculado a uma referência mutável.Ou seja, com seu código você poderia fazer:

vector3 a;
vector3 b(a);

mas não:

vector3 a(some_calculation()); // some_calculation returns a vector3

Além disso, seu operator= está incorreto.Assim como o construtor de cópia, geralmente deve levar um tempo const&, mas deve retornar uma referência para this.É assim que funciona o encadeamento:

int a, b, c;
a = b = c = 0;
// a.operator=(b.operator=(c.operator=(0)));

Devolver um temporário é pouco ortodoxo e não leva a nada.No seu caso, você poderia atribuir repetidamente e nunca alterar o valor. Esquisito:

vector 3 a, b;
a = b; // doesn't change a...?!

operator= precisa mudar this.

Outras dicas

Vector3 (Vector3 e V);

Isso realmente deveria ser vector3( const vector3 &v );

Como você retorna um valor temporário, você deve ligar para um construtor de cópias que requer uma referência const.

Não quero chamar o construtor de cópias.

O que você quer é irrelevante. Você precisar um construtor de cópia aqui. operator = Não é chamado nessa situação, o construtor de cópias é. Além disso, a assinatura está errada, deve ser

vector3& operator =(vector3 const& other);

O argumento também pode ser passado por valor (mas este é um truque avançado ...), mas o valor de retorno verdade devo Seja uma referência não consultiva.

(A assinatura do seu construtor de cópias também não é convencional, consulte a resposta de James.)

Faço vector3 vector3::operator =(vector3 p) Use referências para que você não precise criar uma cópia.

vector3& vector3::operator =(vector3& p);

Você não queria criar um objeto copiado em primeiro lugar.

É uma boa prática em C ++ fazer uma das duas coisas, dependendo se você deseja que seu objeto seja copiado (ou seja, atribuível a outra variável) ou não. Se você precisar fornecer o operador e o construtor de cópias. Por exemplo:

class Point
{
public:
    Point ()                          { }
    Point (int x, int y)              : mX(x), mY(y) { }
    Point (const Point& p)            : mX(p.mX), mY(p,mY) { }

    Point& operator = (const Point& p)    { mX = p.mX; mY = p.mY; return *this; }

    int X () const                    { return mX; }
    int Y () const                    { return mY; }

private:
    int mX;
    int mY;
};

Se você não quiser copiar, pode colocar o protótipo do construtor de cópias e do operador atribuído em uma seção particular e não fornecer uma implementação. Qualquer tentativa de copiá -lo fornecerá um erro do compilador.

Sempre que você usa esse tipo de código:

Point P = anotherP;

O construtor de cópias será chamado. Se você usar esse tipo de código:

Point P;
P = anotherP;

O operador atribui será chamado.

Espero que ajude.

Quando você "passa por valor", como você está em sua definição de operador =, uma cópia do tipo é feita para usar um valor como local para o método. Seu operador não está sendo chamado porque o sistema não consegue encontrar um contrato que pega o Vector3 - você definiu um construtor de cópia que leva o Vector3 &.

Portanto, como outros declararam, o que você deseja fazer é definir seu operador = como tomar

const vector3& p

Você também deve atualizar seu construtor de cópia declarada para tomar o const Vector3 também.

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