Multiplication operator overloading - c++

I am implementing a class Vector and defined the multiplication operator as a member of the class as
Vector operator*(const float& s);
as far as I understand, this means that the left operand is a Vector and the right operand is a float. So if I try and do something like this
Vector c(1,2,3);
Vector d = c * 2.0f; // Results in d = (2,4,6)
that's ok, however, to my eyes is weird to see first the vector then the scaling factor, so in order to have float * Vector I defined a non-member function as
Vector operator*(const float& s, const Vector& v)
{
//Invalid operands to binary expression 'const Vector' and 'float'
return v * s;
}
However I received the error in the comment. I don't know what am I missing or if this is not the way I should declare the operator in order to do the scaling in float * Vector fashion.

Notice that you're passing v as const Vector &, but your member operator* is not marked as const. So it can only be called on non-const Vector objects. This is most certainly not what you want, so just mark the member as const:
Vector operator*(const float& s) const;

Related

Multiplying a vector by scalar and type casting (C++)

I am implementing a vector in 3D space: {u, v ,w}. I want to overload operator * such that the following operation is possible: ResultVector = scalar * Vector. In this expression I supposed that the type contained in the ResVector is the most common between the type of scalar and the type that contained in the Vector. For example, I expect the following type conversions:
int * vector<float> -> vector<float>
complex<float> * vector<float> -> vector<complex>
and so on. But I see that my overload of operator * does not work properly. So, how should I define operator* to provide the type conversions mentioned above and others?
What I have now:
template <typename Scalar>
Vector3<Scalar> operator*(Scalar number, const Vector3<Scalar>& vec1)
{
Vector3<Scalar> tmp(vec1);
tmp *= number;
return tmp;
}
That overloading works only if number is the Scalar and vec1 contains Scalar. Moreover, operator* cannot be used like that
Vector3<float> vec1(1, 2, 3);
Vector3<float> vec5(2 * vec1);
since the appropriate type casting does not exist or operator* that accept appropriate types is not defined. But if I define operator* in the folowing way
template <typename Scalar, typename Multiplier=Scalar>
Vector3<Scalar> operator*(Multiplier number, const Vector3<Scalar>& vec1)
{
Vector3<Scalar> tmp(vec1);
tmp *= number;
return tmp;
}
then the use case mentioned above, is possible. Why? How it works?

How does the compiler choose the right function?

I wrote a small 3d vector class. In particular I wrote two functions, one for rotating the vector and one intended to return a rotated copy of the vector itself. so I have the followig:
Vector Vector::Rotate(const double angle, Vector& axis) const {
Vector b=*this;
b.Rotate(angle,axis);
return (b);
}
void Vector::Rotate(const double angle, Vector & axis) {
/* let's promote this vector to a quaternion */
Quaternion V (0,*this);
/* quaternion describing the rotation */
Quaternion q (cos(angle/2),axis*sin(angle/2));
/* actual rotation */
*this = (q*V*q.conjugate()).Vec();
}
now, when I write something like this:
vector2 = vector1.Rotate(rbo::M_PUCKER,i);
I obtain the error:
no operator "=" matches these operands
operand types are: Vector = void
I expect the compiler to understand what I want: why does he choose the void version instead of the other one returning a vector? Moreover, is it a good practise writing more versions of the same functions the way I did?
The compiler picks the const or non-const overload depending solely on the object on which the member function is called. If the object (or reference) is const it will pick the const overload.
Is it good practice? No. As it seems obvious from the fact that you got yourself confused on what the compiler should do. It is usually good practice to write code that can be easily read and interpreted without confusion :)
The return type does not participate in overload resolution. In other words you can't have functions that only differ in return type.
I think your code only compiles because one of those functions is "const".
if vector1 is not const ,it will choose
void Vector::Rotate(const double angle, Vector & axis)
for member function, there is a hiden parameter this,
Vector Vector::Rotate(const double angle, Vector& axis) const
//actually is
Vector Rotate(const Vector const * this,const double angle, Vector& axis) const
void Vector::Rotate(const double angle, Vector & axis)
//actually is
void Rotate(Vector const * this,const double angle, Vector& axis)
the pointer of your object vector1 is vector *
I guess the compile will choose the best match one

Overloading operator in c++

I am trying to overload the * operator in order to multiply two objects (dot product).
These objects can be Point3D, Vector3D or Normal. They all basically have the same structure (an x, y, and z value), I've only split them up for semantics.
The line that is giving me trouble is this:
float t = (point - r.origin)*normal / (r.direction * normal);
Here, point and r.origin are a Point3D, normal is a Normal and r.direction is a Vector3D. In the header files for these classes I have the following overload functions:
In Vector3D.h:
Vector3D operator *(Normal& n);
In Point3D.h:
Point3D operator -(Point3D& p);
Point3D operator *(Normal& n);
The error I get is:
No match for 'operator*' in 'r->Ray::direction * ((const Plane*)this)->Plane::normal'
Assuming I have correctly filled out the functions in the .cpp file, is there anything stupid I've done here? Also, ignore the fact that there is no division operator yet...It's in the pipeline!
Cheers
You may have defined the unary versions instead of the binary versions. (Did you define them inside the class { ... } ? )
Or you may have not defined them as const. Try this:
Vector3D operator *(const Normal& n) const;
Point3D operator -(const Point3D& p) const;
Point3D operator *(const Normal& n) const;
For binary functions over hetrogeneous parameters like this I find it a lot easier to define them all together at global scope in a seperate file/place and friend them from the classes.
Your this appears like it might be const (just guessing from the error message, since you haven't included that code in your question). Try:
Vector3D operator *(const Normal& n);
Point3D operator -(const Point3D& p);
Point3D operator *(const Normal& n);

Function outside of class in C++ [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Operator overloading outside class
I'm not great with C++ but I've been tasked with creating a custom Vector class that uses a lot of operator overloads. I'm having a hard time grasping how to do one of them.
The class should provide functions for the following:
v3 = v2 * 2.0f;
v3 = 2.0f * v2;
I successfully implemented the first one by overloading the * operator. I'm not sure how to go about the second one though. I know I need to overload the * operator again, but I don't think it should be inside of my vector class. I was absent from class the day my professor explained it, and when I talked to him afterwards he mentioned that it needs to be outside of the class. The problem is that I have no idea how that will work. Any guidance would be great!
EDIT-
#Fede_Reghe That makes sense to me, but when I added it I am now getting this error from the compiler:
Vector.h:64: error: passing ‘const Vector’ as ‘this’ argument of ‘float Vector::operator’ discards qualifiers
In the header, I have these two lines that refer to the * overloads.
Vector operator * (float);
friend Vector operator*(float, const Vector&);
Then I overloaded the [] so that it returns a float of the x, y, or z value. That looks like this in the header:
float operator [] (int);
Outside of the class, I defined the friend * overload like this:
Vector operator * (float f,const Vector& v2)
{
float newX = v2[0] * f;
float newY = v2[1] * f;
float newZ = v2[2] * f;
Vector newVector(newX, newY, newZ);
return newVector;
}
I don't fully understand what the error message means.
You should overload operator outside class and declare it as friend of the class.
For example:
class Vector {
// ...
friend Vector operator*(float, Vector);
};
Vector operator*(float num1, Vector num2)
{
// ...
}
You need the two-argument implementation of operator *(). Here is an example of doing so with operator +() that you can generalize.

Const correctness and operator *

I defined a class like this:
Quaternion& conjugate(); //negates the vector component of the quaternion
Quaternion conjugate() const; //same but in without modifying the class...
Quaternion& operator = (Quaternion const& Qrhs);
Quaternion& operator *= (Quaternion const& Q);
Quaternion operator * (Quaternion const& Qrhs) const;
now I use this functions like this:
PRINTVAR(*this); //this is the first time printed (a little macro to print line and file)
Quaternion vQ(0.,vn), resQ;
resQ = vQ*(this->conjugate()); //this is the method I want to discuss...
PRINTVAR(*this); //this is the second time
resQ = *this * resQ;
and this is the output
*this: (0:0:0:0) at line: 128 in file: Quaternions.cpp
*this: (-0:-0:-0:0) at line: 131 in file: Quaternions.cpp
I thought that by calling the operator * in the line resQ = vQ*(this should be called as const)...
why if I print *this again is changed?
here is the definition of the conjugate function:
Quaternion& Quaternion::conjugate(){
/* Given: Nothing
* Task: Invert sign of the vector
* Return: the class which will be modified
*/
V3 vec;
vec = -(this->getVector());
x() = vec[0];
y() = vec[1];
z() = vec[2];
return *this;
}
Quaternion Quaternion::conjugate() const{
Quaternion result(*this);
result.conjugate();
return result;
}
If the code you showed is in a non-const method, than the this pointer is non-const, and the non-const conjugate method is of course a better match than the const one. Return types aren't considered in overload decisions. If you want to insist that the const version is used, you can add constness: resQ = vQ*(static_cast<const Quaternion*>(this)->conjugate());
Probably the method in which you are using this is non-const.
The type of this a member function of a type A, is A * const. For const member function it is const A * const.
Therefore, your code will work as you expect it to do if you enter your code into const method.
If you want to force calling const overload of function you will need to do a const-cast:
const_cast<const Quaternion * const>(this)->conjugate();
*this is not const (although it is used in a const method), and the c++ FAQ Lite states regarding const overloading (in the FAQ's case on a subscript operator);
When you apply the subscript operator to a MyFredList object that is
non-const, the compiler will call the non-const subscript operator.
Translated, since *this is non-const, the non-const method will be called.