How can I modify the following code in such way I don't need to repeat f2=11;
f3=12; in the main function. The code is for overloading the most common operators.
class FLOAT{
private:
float x;
public:
FLOAT(){ x=0.0; }
void setFloat(float f) { x=f; }
float getFloat() { return x;};
FLOAT operator+(FLOAT obj) {x=x+obj.x; return *this;};
FLOAT operator-(FLOAT obj) {x=x-obj.x; return *this;};
FLOAT operator*(FLOAT obj) {x=x*obj.x; return *this;};
FLOAT operator/(FLOAT obj) {x=x/obj.x; return *this;};
FLOAT& operator=(const FLOAT& obj) {this->x=obj.x; return *this; };
FLOAT& operator=(const float& y) {this->x=y; return *this; };
};
int main() {
FLOAT f,f2,f3;
f2=11;
f3=12;
f=f3-f2;
cout<<"f3-f2 ="<<f.getFloat()<<endl;
f2=11;
f3=12;
f=f3+f2;
cout<<"f3+f2 ="<<f.getFloat()<<endl;
f2=11;
f3=12;
f=f3*f2;
cout<<"f3*f2 ="<<f.getFloat()<<endl;
f2=11;
f3=12;
f=f3/f2;
cout<<"f3/f2 ="<<f.getFloat()<<endl;
system("pause"); // to pause console screen
return 0;
}
#Oli's answer pretty much says you what minimal thing you need to do in order to make your code work. However, I see (and I know even #Oli sees) that your implementation of the class has many flaws.
Since you've implemented FLOAT, I'm explaining you the implementation of Double (the implementation of FLOAT would be similar).
class Double {
double data;
public:
Double (double p=0.0) : data(p){}
double value() { return data; }
Double & operator+=(Double const & other)
{
data += other.data;
return *this;
}
Double & operator-=(Double const & other)
{
data -= other.data;
return *this;
}
//...
};
Note that you don't need to implement operator=(Double const&) and Double(Double const&). The compiler generated ones would be enough. Since the constructor takes one argument of type double, you don't need to implement operator=(double const &) also. The compiler generated copy-semantics, along with the constructor, would take care of that.
Now see this,
//implement operator+ and operator- as non-member functions
Double operator+(Double a, Double const & b)
{
a += b; //a is local copy, so we can change it
return a;
}
Double operator-(Double a, Double const & b)
{
a -= b; //a is local copy, so we can change it
return a;
}
Note that I've implemented operator+ and operator- in terms of operator+= and operator-= respectively.
Similarly, you can implement operator/= and operator*= as member functions, and then implement operator/ and operator* in terms of the them!
Your operators should create a new instance; they shouldn't be modifying themselves (in fact, they should be declared const to prevent this).
e.g.:
FLOAT operator+(FLOAT obj) const
{
FLOAT tmp;
tmp.setFloat(x + obj.x);
return tmp;
}
Note there are much more idiomatic ways of defining operator overloads (e.g. defining operator+ in terms of operator+=, and defining a constructor that takes a float). But the above should suffice.
Related
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...
So, i have a simple class:
class complex{
private:
double a,b;
public:
void setA(double a){ this->a=a; }
void setB(double b){ this->b=b; }
double getA(){ return a; }
double getB(){ return b; }
friend complex operator+(const complex&, const complex&);
};
And i have the actual overloaded operator here:
complex operator+(const complex& x, const complex& y){
complex c;
c.a=x.a+y.a;
c.b=x.b+y.b;
return c;
}
I must have the operator overloaded outside of the function. In order to have access to private variables (those also HAVE to be private) I befriended the class with the function. I don't know if that's correct way to do such things, but at least it works.
I want to be able to add an integer to both members. In main():
complex a;
a.setA(2);
a.setB(3);
a+5;
Would result in having a.a=7 and a.b=8. Such overload inside the class is quite easy to make (Again, don't know if that's good solution, if not please correct me):
complex operator+(int x){
this->a+=x;
this->b+=x;
}
But I have no idea how to make it outside of the class because i can't use "this" pointer.
The usual approach to this sort of problem is to have member functions that define the reflexive version of arithmetic operators and free functions that define the non-reflexive version, implemented with the reflexive version. No friend declarations needed. For example:
class complex {
public:
complex& operator+=(const complex& rhs) {
x += rhs.x;
y += rhs.y;
return *this;
}
private:
double x, y;
};
complex operator+(const complex& lhs, const complex& rhs) {
complex result = lhs;
result += rhs;
return result;
}
Having a+5 change the value of a is unusual, but if that's really wha you want, make operator+(int) a member. However, users would typically expect that a+5 would leave a unchanged, and that a += 5 would modify a.
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;
Is it possible to create an overload for the ostream operator that does an arithmetic operation (addition for example) and then streams out the result? The standard ostream overload that can be found all over the web can only stream from a single variable. I need something that does the following:
std::cout << x+y << std::endl;
or even more complex expressions like:
std::cout << x*y+(3*z)^2 << std::endl;
where x, y, and z are instances of a simple custom-made struct where arithmetic operations are already defined (overloaded).
EDIT:
Here is my code:
struct scalar //complex scalar data structure
{
friend scalar operator^(const scalar&, int); //integer power operator overload
friend scalar exp(const scalar&); //exponential power function
std::ostream& operator<<(std::ostream&, const scalar&)
protected:
double re;
double im;
public:
double real() {return re;} //returns the real part
double imag() {return im;} //returns the imaginary part
scalar(double _re, double _im) {re=_re;im=_im;} //constructor 1
scalar(double _re) {re=_re;im=0.0;} //constructor 2
scalar(const scalar& s): re(s.re), im(s.im) {} //copy constructor
scalar& operator=(const scalar& rhs) //assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
re=rhs.re; //sets real parts equal
im=rhs.im; //sets imaginary parts equal
return *this;
}
scalar& operator+=(const scalar& rhs) //compound addition-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
re=re+rhs.re; //adds real parts
im=im+rhs.im; //adds imaginary parts
return *this;
}
scalar& operator*=(const scalar& rhs) //compound multiplication-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
double x1=re; double x2=rhs.re; double y1=im; double y2=rhs.im;
re=x1*x2-y1*y2; //multiplies real parts
im=x1*y2+x2*y1; //multiplies imaginary parts
return *this;
}
scalar& operator-=(const scalar& rhs) //compound subtraction-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
re=re-rhs.re; //adds real parts
im=im-rhs.im; //adds imaginary parts
return *this;
}
scalar& operator/=(const scalar& rhs) //compound division-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
double x1=re; double x2=rhs.re; double y1=im; double y2=rhs.im;
double n;
n =pow(x2,2)+pow(y2,2);
if (n==0) throw(1);
re=(x1*x2+y1*y2)/n; //multiplies real parts
im=(x2*y1-x1*y2)/n; //multiplies imaginary parts
return *this;
}
const scalar operator+(const scalar& b) //addition operator overload
{
scalar c = *this;
c+=b;
return c;
}
const scalar operator*(const scalar& b) //addition operator overload
{
scalar c = *this;
c*=b;
return c;
}
const scalar operator-(const scalar& b) //addition operator overload
{
scalar c = *this;
c-=b;
return c;
}
const scalar operator/(const scalar& b) //addition operator overload
{
scalar c = *this;
c/=b;
return c;
}
};
scalar i(0.0,1.0);
scalar j(0.0,1.0);
std::ostream& operator<<(std::ostream& out, const scalar& s)
{
out << s.re << '+' << s.im << 'i';
return out;
}
scalar operator^(scalar a, int b) //integer power operator overload
{
double x=a.real(); double y=a.imag();
if (x==0) throw(1);
int r=sqrt(pow(x,2)+pow(y,2));
int arg=atan2(y,x);
scalar c(r*cos(arg),r*sin(arg));
return c;
}
scalar exp(const scalar& s) //exponential power function
{
double x=s.re; double y=s.im;
scalar c(exp(x)*cos(y),exp(x)*sin(y));
return c;
}
Here is my main function:
int main()
{
scalar x(3,4);
scalar y=2;
cout << x*y << endl;
return 0;
}
This is is the output it is supposed to give:
6+8i
And this is the errors it gives instead:
In function 'std::ostream& operator<<(std::ostream&, const scalar&)':|
error: passing 'const scalar' as 'this' argument of 'double scalar::real()'
discards qualifiers|
And if I remove the const as the compiler says, I will get the following error:
error: no match for 'operator<<' in 'std::cout << scalar::operator*(const scalar&)
(((const scalar&)((const scalar*)(& y))))'|
The << operator can't handle the full expression - and why should it?
You need to implement the separate operators (operator+, operator*, ...) for your struct, which take your structs as parameters, do the corresponding operation on it, and return another of your structs. And only then define a operator<< taking a single one of your structs.
How would you even think of passing in such a complex structure to the operator<<, let alone parse it in there? Implement the separate operators, and leave the parsing to the compiler.
e.g. for a simple struct only encapsulating an int, doing that with + operation would look like this:
struct mystruct
{
int value;
};
then define:
mystruct const operator+(mystruct const & a, mystruct const & b)
{
mystruct result;
result.value = a.value + b.value;
return result;
}
and
std::ostream & operator<<(std::ostream& out, mystruct const & a)
{
out << a.value;
return out;
}
then you can do:
mystruct a, b;
a.value = 1;
b.value = 2;
std::cout << a+b;
Edit: With your updated code, there's exactly one problem:
std::ostream& operator<<(std::ostream&, const scalar&)
should be
friend std::ostream& operator<<(std::ostream&, const scalar&);
i.e. you're missing friend and an ;
Though the error you show suggests some different problem (which jrok's answer would have a solution for) - that doesn't seem to result from compiling the code you show! So please get the shown code and error message in sync.
The error is because functions scalar::real and scalar::imag are not const - you can only call const member functions when you've got a reference to a constant scalar.
double real() const {return re;}
double imag() const {return im;}
Why don't you just write std::cout << (x+y) << std::endl;
and be done?
As long as your overloaded operator takes its argument by value:
ostream& operator<<(ostream&, Thing)
or constant reference:
ostream& operator<<(ostream&, const Thing&)
you can use it for any expression with type Thing.
You should put parentheses around complex expressions, to avoid surprises from operator precedence; in particular, the second expression involving ^ won't be parsed as you expect.
You'll only be restricted to a single variable (or, more accurately, an lvalue expression) if the operator requires a non-constant reference; so don't do that.
UPDATE Now we've seen the code, the main issue is the in-class definition of operator<< as a member function; it can't be a member. Perhaps you want it to be a friend, so it can access im and re; or perhaps you should remove the declaration (making it a non-member, non-friend), and just use the public interface. If you do that, you'll need to add const to real() and imag(), so they can be called on a const object. You should do that anyway.
(Looking at the reported error, it seems you've already changed it to use the public interface, but haven't declared the necessary functions const).
I am trying to overload (*,+,-,/,=) opertors in FLOAT class. I wrote this class:
class FLOAT{
private:
float x;
public:
FLOAT(){ x=0.0; }
void setFloat(float f) { x=f; }
void operator+(FLOAT obj) {x=x+obj.x; };
void operator-(FLOAT obj) {x=x-obj.x; };
void operator*(FLOAT obj) {x=x*obj.x; };
void operator/(FLOAT obj) {x=x/obj.x; };
FLOAT& operator=(const FLOAT& obj) {this->x=obj.x; return *this; };
};
and I use it such:
int main() {
FLOAT f,f2,f3;
f.setFloat(4);
f2.setFloat(5);
f3=f+f2;// here is the problem!
system("pause");//to pause console screen
return 0;
}
f3=f+f2 seems not right. What can I do?
I think your implementations of the operators will not do what you want. For example:
FLOAT f1; f1.setFloat(1.0);
FLOAT f2; f2.setFloat(2.0);
FLOAT f3;
f3 = f1 + f2;
Assuming that you change operator+(), for example, to return a FLOAT, you will still have the effect that after the addition, f1 and f3 will both equal 3.0;
A commonly used idiom is to implement the operators like += in the class, and the operators like + outside the class. For example:
class FLOAT {...
FLOAT& operator+=(const FLOAT& f)
{
x += f.x;
return *this;
}
};
...
FLOAT operator+(const FLOAT& f1, const FLOAT& f2)
{
FLOAT result(f1);
f1 += f2;
return f1;
}
A side benefit of this is that you can also easily add other operators like
FLOAT operator+(int x, const FLOAT& f);
FLOAT operator+(double x, const FLOAT& f);
Doing a thorough job on a class like this is good practice for when you want to do this work with more interesting types like complex numbers or matrices. Be sure you add the comparison operators, copy constructor, destructor and assignment operators for completeness. Good luck!
Your operators are the equivalent of +=, -=, etc.
If you want to +, you also need to return a value!
FLOAT operator+(FLOAT obj)
{
FLOAT tmp;
tmp.x = x+obj.x;
return tmp;
}
You can't assign the return value of a void function to anything, because it doesn't return anything. Declaring the operator overloads as friend functions is frequently much more flexible. Your class and functions should be more like this:
class FLOAT {
friend FLOAT operator+( const FLOAT & a, const FLOAT & b );
/* ... rest of class ... */
};
FLOAT operator+( const FLOAT & a, const FLOAT & b )
{
FLOAT temp( a );
temp.x += b.x;
return temp;
}
You should return the result in each case. Also pass an argument by reference so it will not be copied and add some const qualifiers. For + it might look like:
FLOAT operator+(const FLOAT& obj) const
{
FLOAT res;
res.x = x + obj.x;
return res;
}
Note you might not want to return const, as you would like go get modifiable object.
void operator+(FLOAT obj) {x=x+obj.x; };
What is wrong in this code?
It returns void and you want to assign this somewhere. No go.
FLOAT & FLOAT::operator=(const FLOAT &rhs) {
... // todo assignment here
return *this; // Return a reference to myself.
}
FLOAT & FLOAT::operator+=(const FLOAT &rhs) {
... //todo implement compound + operator
return *this; // Return a reference to myself.
}
const FLOAT FLOAT::operator+(const FLOAT &rhs) const {
return FLOAT(*this) += other; //that's already done :)
}
operator+ has return type void. It should probably return a FLOAT.
To clarify by example, void operator+(FLOAT obj) {x=x+obj.x; }; should in stead look like FLOAT operator+(FLOAT obj) { return obj.x + x; }. This is because, as others have pointed out, a function with return type of void cannot return any value. Since operator+ is generally expected to return a value that represents the result of addition, you should return a FLOAT object that holds this result.