I'm supposed to do an overloading of the modulus function, but I'm not sure how to do it. Let me know if you require more information.
This is my requirement by my school:
Member function that rotates a Point about the origin by the specified number of degrees. Returns a new Point
Inside the driver file, my school wants the modulus function to accomplish this scenario:
Point pt1(-50, -50);
double angle = 45;
Point pt2 = pt1 % angle;
This is what I've tried:
Point Point::operator%( int value)
{
(int)x%value;
(int)y%value;
return *this;
}
//point.h file
class Point
{
public:
// Constructors (2)
explicit Point(double x, double y);
Point();
double getX() const;
double getY() const;
Point operator+(const Point& other)const ;
Point& operator+(double value);
Point operator*(double value) ;
Point operator%(int value);
Point operator-(const Point& other)const ;
Point operator-(double value);
Point operator^(const Point& other);
Point operator+=(double value);
Point& operator+=(const Point& other) ;
Point& operator++();
Point operator++(int);
Point& operator--();
Point operator--(int);
Point& operator-();
// Overloaded operators (14 member functions)
friend std::ostream &operator<<( std::ostream &output, const Point
&point );
friend std::istream &operator>>( std::istream &input, Point
&point );
// Overloaded operators (2 friend functions)
private:
double x; // The x-coordinate of a Point
double y; // The y-coordinate of a Point
// Helper functions
double DegreesToRadians(double degrees) const;
double RadiansToDegrees(double radians) const;
};
// Point& Add(const Point& other); // Overloaded operators (2 non-member, non-friend functions)
// Point& Multiply(const Point& other);
Point operator+( double value, const Point& other );
Point operator-( double value, const Point& other );
The first error I see is that you didn't respect the requirements of your assignement. Your assignement specifically ask for your type to support this operation:
Point pt1{-50, 50};
Point pt2 = pt1 % 45.5;
This infer that your operator must return a point with the operation apply to it using a double. You clearly store the angle as double, but receive an int. That is not respecting your requirement. Also, you return a rotated point, but not the right one. You're making the operation in-place instead of making the operation on a new point. Inside your operator, you should create a point with the new position. Something like this:
Point Point::operator%(double) const {
return Point{..., ...};
}
Then, your operation is wrong. You cast the point data member to intonly to do a modulo on them. A modulo don't do a rotation. A rotation is usually done with a sine and a cosine. You cannot use the C++ %operator on int to make a rotation.
Related
I have been encountering an issue where I overloaded the [] operator and I am running into issues when compiling my code.
The overload defintion
double& Point::operator[](int index) { return index ? y : x; }
The class Point
`class Point {
public:
// declare constructors (3)
Point();
Point(double * arr);
//Point(double x_input, double y_input);
Point(const Point& input);
Point(const double x_input, const double y_input);
// declare overloaded operators (8 member functions)
double& operator[](int index);
Point operator+=(double num);
Point operator+=(const Point& pointee);
Point operator++(int);
Point operator++();
Point operator--(int);
Point operator--();
private:
double x; // The x-coordinate of a Point
double y; // The y-coordinate of a Point
};`
The error:
error
I am not sure as to why I am encountering this issue and I was hoping if someone can shed some light as to what is happening. Thank you in advance.
I have tried adding const to the overload and its return type but to no avail.
The error message means that the operator [] is called for a constant object of the type Point but the operator is not declared as a constant member function.
Add one more overload to the operator
// declare overloaded operators (8 member functions)
double& operator[](int index);
const double& operator[](int index) const;
If the operator is defined in the global namespace outside the class definition then you need to write
const double& hlp2::Point::operator[](int index) const
{
//,,,
}
If the operator is defined in the same namespace where the class is defined then write
const double& Point::operator[](int index) const
{
//,,,
}
Shortly speaking define it as you defined the non-constant operator.
I am stuck with regards to the 2 non-member, 2 non-friend multiplication and the addition of the operator overloading functions. I am unsure of how to do it. Could someone please assist in helping me to resolve this? Refer to my codes below. Thank you in advance!
Compiler output:
Point.cpp:208:19: error: passing ‘const CS170::Point’ as ‘this’ argument discards qualifiers [-fpermissive]
return other + value;
^~~~~
Point.cpp: In function ‘CS170::Point CS170::
operator*(double, const CS170::Point&)’:
Point.cpp:215:10: error: ‘double CS170::Point::x’ is private within this context
result.x = value * x;
^
Point.cpp:215:22: error: ‘x’ was not declared in this scope
result.x = value * x;
^
Point.cpp:216:10: error: ‘double CS170::Point::y’ is private within this context
result.y = value * y;
^
Point.cpp:216:23: error: ‘y’ was not declared in this scope
result.y = value * y;
Point.h
#include <iostream> // istream, ostream
namespace CS1100
{
class Point
{
public:
// Point(double X, double Y); // Constructors (2)
explicit Point(double x, double y);
Point();
Point operator+(const Point& other)const ;
Point& operator+(double value);
Point operator*(double value) ;
Point operator%(double value);
Point operator-(const Point& other)const ;
Point operator-(double value);
Point operator^(const Point& other);
Point operator+=(double value);
Point& operator+=(const Point& other) ;
Point& operator++();
Point operator++(int);
Point& operator--();
Point operator--(int);
Point& operator-();
// Overloaded operators (14 member functions)
friend std::ostream &operator<<( std::ostream &output, const Point &point );
friend std::istream &operator>>( std::istream &input, Point &point );
// Overloaded operators (2 friend functions)
private:
double x; // The x-coordinate of a Point
double y; // The y-coordinate of a Point
// Helper functions
double DegreesToRadians(double degrees) const;
double RadiansToDegrees(double radians) const;
};
// Point& Add(const Point& other); // Overloaded operators (2 non-member, non-friend functions)
// Point& Multiply(const Point& other);
Point operator+( double value, const Point& other );
Point operator-( double value, const Point& other );
My source code:
///////////////////////////////////////////////////////////////////////////////
// 2 non-members, non-friends (operators)
double operator+( double value, const Point& other )
{
return other + value;
}
double operator*( double value, const Point& other )
{
Point result;
result.x = value * x;
result.y = value * y;
return result;
}
As far as I understand the discussion to the question, the problem is not really the operators themselves, but the number of allowed member functions being limited – and you already have exceeded this limit.
However, you have quite a number of functions that don't need to be members, for instance:
class Point
{
public:
Point operator+(const Point& other) const
{
return Point(x + other.x, y + other.y);
}
};
Make free functions from all these:
class Point { /*...*/ };
Point operator+(Point const& l, Point const& r)
{
return Point(l.getX() + r.getX(), l.getY() + r.getY());
}
Having moved out all these operators like the one shown above, you get away far enough from the limit so that you can introduce the needed getters:
class Point
{
public:
double getX() { return x; };
double getY() { return y; };
};
If you are willing to rename the member variables, e. g. by adding a prefix, you can follow another pattern:
class Point
{
double m_x, m_y;
public:
double x() { return m_x; };
double y() { return m_y; };
void x(double v) { m_x = v; }; // the corresponding setter
// (for illustration, you might not need it)
};
This latter pattern is quite common, too. Advantage is being shorter for skipping the explicit get or set prefix, disadvantage is exactly losing this explicitness... Decide you, which one you prefer. More important than personal preference is consistency, though, so if there's e. g. a company's convention or common practice, follow that one...
Some of your operators will need to remain members, though, these are all those that modify the current object:
class Point
{
public:
Point& operator+=(const Point& other) /* const */ // NEEDS to be non-const
{
x += other.x;
y += other.y;
return *this; // <- very good hint to spot the ones needing to stay members
}
};
If you have a public copy constructor, you can re-use the operator+= for defining the operator+:
class Point
{
public:
Point(Point const& other) : Point(other.x, other.y) { }
};
Point operator+(Point const& x, Point const& y)
{
Point r(x); // or Point(x.x(), x.y()), if you lack such constructor)
r += y;
return r;
}
Actually, you can even spare the explicit copy by accepting one of the parameters by value:
Point operator+(Point x, Point const& y)
// ^ no reference
{
return x += y;
}
The latter rather for illustration, I'd prefer the two references in given case to keep the symmetry of the interface...
I have the following Point class.
#ifndef POINT_HPP
#define POINT_HPP
#include <string>
class Point {
private:
double m_x, m_y;
public:
Point();
Point(double x, double y);
Point(const Point &p);
~Point();
// selectors
double X() const;
double Y() const;
std::string ToString() const;
double Distance() const;
double Distance(const Point &p) const;
// modifiers
void X(double x);
void Y(double y);
Point operator - () const; // Negate coordinates
//Point operator * (double factor) const; // Scale the coordinates.
Point operator + (const Point & p) const; // Add coordinates.
bool operator == (const Point & p) const; // equally compare
operator.
Point& operator = (const Point& source);
Point& operator *= (double factor);
// non member function to facilitate commutative
multiplication
friend Point operator * (double factor, const Point & p);
friend Point operator * (const Point & p, double factor);
};
Point operator * (double factor, const Point & p) {
return Point(p.m_x * factor, p.m_y * factor);
}
Point operator * (const Point & p, double factor) {
return factor * p;
}
#endif //POINT_HPP
When creating a two Point objects and attempting to perform multiplication with the implemented * operator. I get a multiple definition error. I believe that my * operator is overloaded to so that I can perform double * Point object and Point object * double in any order. Did I declare the friend functions in the incorrect place or provide implementations in the wrong place?
They need to be marked inline if the functions are defined in a header file that will be included from multiple .cpp files. Either that or move the definition (implementation) into a .cpp file. Each .cpp file that includes the header file the way it is now is creating a definition and when they are all linked together, you then have "multiple definitions"
inline Point operator * (double factor, const Point & p) {
return Point(p.m_x * factor, p.m_y * factor);
}
inline Point operator * (const Point & p, double factor) {
return factor * p;
}
It is allowed to define friend functions within the class. Doing so will make them inline.
From CPP reference
A function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function, is implicitly an inline function.
If you do this, you can avoid the multiple definition problem.
Suppose I have the following class:
class Point{
private:
int x,y;
public:
int get_x() const {return x;}
int get_y() const {return y;}
Point() :x(0),y(0){}
Point(int x,int y):x(x),y(y){}
Point(const Point& P){
x = P.get_x();
y = P.get_y();
}
Point& operator= (const Point& P) {
x = P.get_x();
y = P.get_y();
return *this;
}
friend ostream& operator<<(ostream& os,const Point& P) {
os<<"["<<P.get_x()<<", "<<P.get_y()<<"]";
return os;
}
Point operator - (const Point &P){
return Point(x-P.get_x(),y-P.get_y());
}
friend bool operator > (const Point &A, const Point &B) {
return A.get_y()>B.get_y();
}
};
Here I used friend function. I can also use function without friend:
class Point{
...
bool operator > (const Point &B) const {
return y>B.get_y();
}
...
};
What are the differences between them in actual implementations? Also in the second method, the code won't compile without 'cont', why is that? Even after I changed the getter function into non-const function, it still won't compile without the 'const'.
As you've already noticed, comparison operator overloads can either be implemented as a member function or as a non-member function.
As a rule of thumb you should implement them as a non-member non-friend function where possible, as this increases encapsulation, and it allows (non-explicit) conversion constructors to be used on either side of the operator.
Say for instance your Point class for whatever reason had an int conversion constructor:
Point(int x);
With a non-member comparison operator you can now do the following:
Point p;
p < 3; // this will work with both a member and non-member comparison
3 < p; // this will **only** work if the comparison is a non-member function
You also seem to be confused about when to use const, again as a rule of thumb for comparison operators you should always use const wherever possible, because comparisons logically do not involve any change to the object.
As Point is a very small class you could also take it by value instead, so in order of most to least preferable your options are:
// Non-member, non-friend
bool operator>(Point const& A, Point const& B);
bool operator>(Point A, Point B);
// Non-member, friend
friend bool operator>(Point const& A, Point const& B);
friend bool operator>(Point A, Point B);
// Member
bool Point::operator>(Point const& B) const;
bool Point::operator>(Point B) const;
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Operator Overloading in C++ as int + obj
Operator overloading c++-faq
I have a Point object with this operator:
Point operator +(float other) const {
return Point(x + other, y + other, z + other);
}
I can perform addition like so:
point + 10
But I can't perform it in reverse order:
10 + point
Is there another operator I need to overload in order to provide this functionality?
You normally want to overload the global operator:
Point operator+(Point const &a, float b);
Point operator+(float a, Point const &b);
Instead of two overloads, you may want to use only one overload:
Point operator+(Point const &a, Point const &b);
and then have a ctor to create a Point from a float:
class Point {
public:
Point(float);
};
In this case, adding a float to a Point will use the ctor to convert the float to a Point, then use your overloaded operator+ to add those two Points together.
As a free function:
Point operator+(float other, const Point &pt) {
return pt+other;
}
Given an existing Point& Point::operator+=(float other), add these two free functions:
Point operator+(Point pt, float other) {
return pt += other;
}
Point operator+(float other, Point pt) {
return pt += other;
}
Outside of the class:
inline Point operator+(const float& other, const Point& pnt) { return Point(...); };