Operator Overloading

Hi!

I made a class "vec2f" and i was trying to overload its operands. According to what a read, binary operands should be non-members functions. The problem is that when I use the non-member operands it doesn't recongnize them.
Vec2f.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#ifndef VEC2F_H
#define VEC2F_H
#include <cmath>

class Vec2f
{
    public:
        Vec2f():m_x(0), m_y(0)
        {}

        explicit Vec2f(float a, float b): m_x(a), m_y(b)
        {}

        Vec2f(const Vec2f &other): m_x(other.m_x), m_y(other.m_y)
        {}

        Vec2f &operator= (const Vec2f &other);
        Vec2f &operator += (Vec2f const &other);
        Vec2f &operator -= (Vec2f const &other);
        bool operator== (Vec2f const &other) const;


		Vec2f operator-() const {
			return Vec2f(-m_x, -m_y);
		}

        float magnitude() const
        {
            return std::sqrt(m_x*m_x + m_y*m_y );
        }

        Vec2f getNormalized() const
        {
            return Vec2f (m_x / magnitude(), m_y / magnitude ());

        }

        static Vec2f lerp(const Vec2f &a, const Vec2f &b, float c)
        {
           return (b - a) * c + a;
		}

        float m_x;
        float m_y;


};


Vec2f operator+ (Vec2f v1, const Vec2f v2)
{
    return v1 += v2;
}

Vec2f operator- (Vec2f v1,  Vec2f v2)
{
    return v1 -= v2;
}

float operator* (Vec2f& v1, Vec2f& v2) //dot product
{
    return v1.m_x*v1.m_y + v2.m_x*v2.m_y;
}


Vec2f operator* (Vec2f v1, float scalar);



#endif // VEC2F_H 


Vec2f.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "Vec2f.h"

Vec2f &Vec2f::operator=(Vec2f const &other)
{
    if (this == &other) return *this;

    m_x = other.m_x;
    m_y = other.m_y;

    return *this;
}

Vec2f &Vec2f::operator += (Vec2f const &v2)
{
    m_x += v2.m_x;
    m_y += v2.m_y;

   return *this;
}

Vec2f &Vec2f::operator -= (Vec2f const &v2)
{
    m_x -= v2.m_x;
    m_y -= v2.m_y;

   return *this;
}


bool Vec2f::operator == (Vec2f const &v2) const
{
    return(this->m_x == v2.m_x && this->m_y == v2.m_y);
}

Vec2f operator* (Vec2f v1, float scalar)
{
    v1.m_x *= scalar;
    v1.m_y *= scalar;

    return v1;
}


The error:
||=== Build: Debug in Math (compiler: GNU GCC Compiler) ===|
E:\Math\include\Vec2f.h|40|error: no match for 'operator-' in 'b - a'|
E:\Math\include\Vec2f.h|40|note: candidate is:|
E:\Math\include\Vec2f.h|23|note: Vec2f Vec2f::operator-() const|
E:\Math\include\Vec2f.h|23|note:   candidate expects 0 arguments, 1 provided|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|


Thanks!

Asus.
Make use of friend functions for this purpose as friend functions can access private members of a class.

See an example here:
http://www.dailyfreecode.com/code/operator-overloading-friend-function-183.aspx
Last edited on
Thanks for the answer!

But I make the members public. I thought that if you make the members public that wasn't necessary.


Asus.
You don't have a subtraction operator overload. You only overloaded the negation operator on line 23 (-x, not x - y).
The signature for subtraction is Vec2f Vec2f::operator-(const Vec2f &) const;

EDIT: Well, you did overload it in global scope, but you'll have an easier time if you move those overloads to the class scope. Just trust me on this.
Last edited on
Thanks for the answer!!

I did actually, that's the problem. It's in line 55, as a non-member function.

Asus
See my edit.
Thanks again.

I tried moving the overloads and it worked perfectly, like you said. The thing is, I read in several books that's good practice to define binary operators overloads in global scope. For that reason I'm insisting on this, but I can't find why my code isn't working.

Asus.
C++ compilers are single pass except for classes. This means that they only see things that are declared further ahead when inside class scope. There's two solutions if you really want to keep the operators global:

1. Move the global declarations up:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//In header:
//Forward declare the class, or naming the class in the function declaration
//will generate compiler errors.
class Vec2f;

Vec2f operator+ (Vec2f v1, const Vec2f v2);
//etc.

class Vec2f{
//...
};

//In source:
Vec2f operator+ (Vec2f v1, const Vec2f v2)
{
    return v1 += v2;
}
//etc. 

2. Move the class declarations out: leave everything else the same, but move the definitions of lerp() and any other member function that uses those global operators to the source.
Thanks helios! That's what I wanted!
Topic archived. No new replies allowed.