Problem with operator overloading

Hi I have two classes, a Rotation and a Vector (my custom classes, not the standard Vector class).

I want to be able to do
1
2
3
Vector v, v2;
Rotation r;
v2 = v * r;


So I made this operator overload in the vector class:

const Vector& operator*(const Rotation &rot);

Now it will not compile because it says:

error C2440: 'initializing' : cannot convert from 'btQuaternion' to 'Vector'


on the line v2 = v * r;

Thanks for any help you can give on this problem. What am I doing wrong, am I trying to do something that's not possible?

These are my header files:

Vector.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
#pragma once

class btVector;
class btTransform;
class Rotation;
class Ogre::Vector3;

class Vector
{
public:
	float x,y,z;

public:
	Vector(void);
	Vector(float x, float y, float z);
	Vector(const btVector3& aVector);
	Vector(const Ogre::Vector3& aVector);

	//operaters
	Vector& operator+=(const Vector &rhs);
	Vector& operator-=(const Vector &rhs);
	Vector& operator*=(const float &value);
	Vector& operator/=(const float &value);
	Vector& operator*=(const Rotation &rot);
	
	const Vector operator+(const Vector &other);
	const Vector operator-(const Vector &other);
	const Vector& operator*(const float &value);
	const Vector& operator/(const float &value);
	const Vector& operator*(const Rotation &rot);
	operator btVector3() const;
	operator Ogre::Vector3 () const;
	operator btTransform() const;



	~Vector(void);
};


rotation.h


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#pragma once

#include "base.h"

class Rotation
{
private:
	btQuaternion q;
public:
	Rotation(void);
	Rotation(const btQuaternion& aQuaternion);
	Rotation(const Ogre::Quaternion& aQuaternion);
	Rotation(const btTransform& transform);


	//operators
	operator btQuaternion() const;
	operator btTransform() const;
	operator Ogre::Quaternion () const;
	

	~Rotation(void);
};
Last edited on
I think the problem is you need const Vector& operator*(Vector& vec,const Rotation &rot) {/*Insert what it does here*/} when defining it (but not declaring it.), and I'm guessing you need a Vector:: for the scope-of operator before that. Why this is escapes me a little, but I'm pretty sure the first argument of a binary operator that returns a data type must be that data type.

Why do you have so many consts?
Last edited on
Why I have so many consts. that is a good question. I looked at examples of operater overloading and they used const there, at least in the parameters. I more or less know what it means, but actually I don't know when I should really use them, and when it doesn't matter. If it's not important I would rather get rid of all the consts. so any suggestions on that?

When I try your idea, it sais too many parameters (if I change the defenition). If I change the declaration it sais it doesn't fit the defenition. I think you only need to supply the left hand side as a parameter if you are making the operator not a member.

What puzzles me: it seems like it casts the rotataion to a btQuaternion (which is possible) and than for some reason it tries to cast it to a Vector.

Could the problem be that you can only overload * once?
Last edited on
Are you sure the error points to that line? It seems like an odd error at that location. That said, it IS possible to do what you're trying to do, and the code looks ok, so I'm wondering if there isn't an error elsewhere.

Regarding consts, it is good practice to use them where applicable. However, I think the +, -, /, and * operators all should be returning 'Vector', rather than 'const Vector' or 'const Vector &'. Consider if you want to do something like:

Vector normalizedVec = (v1 + v2).Normalize();

I don't believe that would work if operator+ returned a const Vector, as 'Normalize()' wouldn't be a const method. The +/-* operators should have 'const' at the END of the declaration though, as they don't modify the Vector on the left side of the equation. So, for +:

Vector operator+(const Vector &other) const;
Last edited on
Make sure that IN THE CLASS, you're declaring it with only one argument, but outside of it, you're declaring it with two. For instance,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;

struct Bill
{
    ostream& operator << (Bill);
};

ostream& operator << (ostream& MyOut,Bill Bob)
{
    MyOut << "You were just Billed.";
    return MyOut;
}

int main()
{
    Bill Bob;
    cout << Bob << endl;
    return 0;
}


works but

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;

struct Bill
{
    ostream& operator << (ostream,Bill);
};

ostream& operator << (ostream& MyOut,Bill Bob)
{
    MyOut << "You were just Billed.";
    return MyOut;
}

int main()
{
    Bill Bob;
    cout << Bob << endl;
    return 0;
}


doesn't. And no, I don't know why I used that particular example with a struct called Bill and outputting "You were just Billed." In case you're wondering, a struct is basically the same as a class, but if no access level (public, protected, private) is specified, the default is public instead of private.
Last edited on
You were right. The error was actually located at that line, but the problem was not directly what I thought it was, also it had to do with the const.

I think the problem was: I defined the * operator in terms of the *= operator

1
2
3
4
const Vector& Vector::operator*(const Rotation &rot)
{
	return Vector(*this) *= rot;
}


and the variable v I was talking about actually also was a const argument. Somehow it couldn't use the * operator if the left hand side is a const. I'm not 100% sure what causes this, but it's fixed now, thanks! If you have a better idea why this exactly goes wrong I still like to know ofcourse!
Last edited on
You can't use a const Vector because none of those operators are declared const.
What draco said. when you call

MyClass objNew, obj1, obj2;
objNew = obj1 + obj2

you are really calling 2 methods. First, to get the output of "obj1 + obj2". To do this, it basically calls "obj1.operator+(obj2)". If obj1 happens to be a const MyClass, we are saying that obj1 can't be changed, and you can't call any method of MyClass on obj1 that will change it. For example, if obj1 were const, you can't do

obj1 += 5;

because in that case, you are altering obj1. For this reason, "operator+=" is never const. "operator+" on the other hand doesn't change the left side, it creates a new object as the result, so we know that operator+ doesn't modify the object on which it's called. Because of this, we can mark the method as being const (by putting the keyword const at the END of the signature).

After that, you are calling objNew.operator=(...), passing in the result of the earlier operator+ call. Obviously this does modify objNew, so this method would not be labeled const.
Ok thanks,

Whovian, I see in your example you need to have the Bill class on the RHS, but in my case, if I need my classes on the LHS, I can just declare the operator with 1 argument, which is the other, and then I can use 'this' for the LHS. At least for me it works that way :) I do add Classname:: before the operator in the declaration

rollie, how important is it to make things const (when they can be). Can you really notice difference in performance, or does it help you prevent making some mistakes? How often do you do it, do you check all arguments in your function if they can be const as much as possible, or shouldn't I worry too much about making things const?
Last edited on
It's unlikely to greatly affect performance, but it does help keep you from making mistakes. I'd recommend getting into the habit of doing it - if you were asked to write code at an interview, correct const usage would definitely be something that might make a potential employer take note of you.
Thanks a lot! I'll try to learn more about it so I can use it properly. so far this website seems like a very good read on the subject:

http://duramecho.com/ComputerInformation/WhyHowCppConst.html
Topic archived. No new replies allowed.