Overloading operator in c++ - 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);

Related

Error C2677: binary '*': no global operator found

Sorry for asking a similar question that has been asked before, but I wasn't able to understand the answers.
Header file
float Dot(const Point& other) const;
CPP
Point Point::operator*(float operand) const
{
return Point(mX * operand, mY * operand);
}
and I am getting Error C2677: binary '*': no global operator found
what is the problem??
You have implemented operator* in the cpp file but in the header file you only declared a simple Dot function.
You either move the operator* inline in the header file or you add a declaration for it in the header file, ie:
Class Point {
[...]
Point operator*( float operand ) const {
return Point( mX * operand, mY * operand) );
}
};
That operator defined that way is a member operator because you have declared inside the class itself. You might also want to add a global operator, for example a comparison operator, which you will place outside your class declaration, for example:
Class Point {
[...]
Point operator*( float operand ) const {
return Point( mX * operand, mY * operand) );
}
};
bool operator==(const Point& left, const Point& right)
{
return left.value == right.value;
};
Final thought:
So to recap the error you've got it most probably means that you didnt' declare the operator* as global operator as shown above. Also I think you might confusing a dot product with a multiplication, (operator*), which held two very different results, also notice one is a scalar operation (in any dimension), the other is a Point, in this case, two dimension.

Why are there two different types of operator overloading for the same operation in Vector3D class?

I was reviewing somebody's code and came up with two interesting operator overloading methods. It is not entirely clear to me why the coder had to code the second method.
First:
inline Vector3D operator-(const Vector3D &a, const Vector3D &b) {
return Vector3D(a.getX() - b.getX(), a.getY() - b.getY(), a.getZ() - b.getZ());
}
Second:
inline Vector3D operator-(const Vector3D &a) {
return Vector3D(-a.getX(), -a.getY(), -a.getZ());
}
I understand what the first one is doing here, but is the second method necessary at all? If yes, what does it do?
The second is a unary operator. It allows you to negate the vector, reflecting it across the origin into the opposite octant.
If we guess that the class has a reasonable constructor and copy constructor, then:
Vector3D v( 1,1,1 );
Vector3D negatedV = -v;

C++ Changing operand order when overloading operators

My problem is in the form Ax = B, where A is a square matrix and, x and B are vectors. I'm defined a Matrix class and am trying to overload the forward slash operator such that B/A would produce x.
The first line of my overloading function is below:
vector<double> Class_A_Matrix::operator/(vector<double> B_Vector)
My code works but only if the order of the operands either side of the operator is A/B. How can I adjust my code such that I can do B/A?
Define and implement a non-member
Class_A_Matrix operator/(const vector<double> &, const Class_A_Matrix &);

Multiplication operator overloading

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;

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.