Search code examples
c++structconstantscopy-constructor

Getting "No valid copy constructor" in C++ on return struct


I'm currently working on implementing a simple 2D vector class Vector2f in C++ using Visual Studio Community Edition 2019.

When I try to return a newly constructed one in a method, such as:

return Vector2f((this->x/sum),(this->y/sum);

I'm getting a hint:

no suitable copy constructor for Vector2f

and an on-compile error:

'return': cannot convert from 'Vector2f' to 'Vector2f'

I've rewritten the class from scratch a few times, and still seem to be getting the error. I don't understand, what exactly is going wrong?

Vector2f_struct.h

#pragma once

#ifndef PMP_VECTOR2F_STRUCT__H
#define PMP_VECTOR2F_STRUCT__H

namespace pmp
{
    struct Vector2f
    {
        /* Elements */
        float x;
        float y;

        /* Methods */

        // Constructors & Destructor
        Vector2f();
        Vector2f(float i, float j);
        Vector2f(Vector2f& og);
        virtual ~Vector2f();

        // Unary Operators
        float magnitude();
        Vector2f normal();
    };
};

#endif

Vector2f_struct.cpp

#include "pmp_Vector2f_struct.h"

#ifndef PMP_VECTOR2F_STRUCT__CPP
#define PMP_VECTOR2F_STRUCT__CPP

/* Dependencies */
#include <math.h>

namespace pmp
{
    Vector2f::Vector2f()
    {
        this->x = 0.0f;
        this->y = 0.0f;
        return;
    };

    Vector2f::Vector2f(float i, float j)
    {
        this->x = i;
        this->y = j;
        return;
    };

    Vector2f::Vector2f( Vector2f& og )
    {
        this->x = og.x;
        this->y = og.y;
        return;
    };

    Vector2f::~Vector2f()
    {
        this->x = 0.0f;
        this->y = 0.0f;
        return;
    };

    float Vector2f::magnitude()
    {
        float c2 = (this->x * this->x) + (this->y * this->y);
        return sqrt(c2);
    };

    Vector2f Vector2f::normal()
    {
        float sum = this->x + this->y;
        return Vector2f(this->x / sum, this->y / sum); // Error here.
    };

};

#endif

Solution

  • The parameter of the copy constructor has a non-constant referenced type

    Vector2f(Vector2f& og);
    

    In the member function normal there is returned a temporary object that is copied. You may not bind a temporary object with a non-constant lvalue reference.

    Redeclare the copy constructor like

    Vector2f(const Vector2f& og);
    

    Or just remove its explicit declaration. In this case the compiler generates it for you.

    Pay attention to that return statements in the constructors and the destructor are redundant.