Overloading Operators - c++

I need your help, please have a look at the following code I get error
as following:
no match for operator *(operand types are'doubles and 'lists')
this is inherited class, header file(before operator* function it worked properly)
class lists:public vectorebi
{
public:
lists (double first_);
lists (double first_, lists var_);
double operator-(const double& answer);
lists operator*(const lists &answer) const;
virtual ~lists(){};
private:
friend std::ostream& operator<<(std::ostream& os, lists& arg);
double first;
lists* var;
};
//soucre file
lists::lists(double first_){
first=first_;
}
lists::lists(double first_, lists var_){
first=first_;
var=&var_;
}
double lists::operator-(const double& answer){
double result = answer - first;
return result;
}
lists lists::operator*(const lists &answer) const
{
lists k = first * answer.first;
return k;
}
std::ostream& operator<<(std::ostream& os, lists& arg) {
os << "(" << arg.var << ")";
return os;
}
and the main ///
int main()
{
double answer1 = 15;
lists k=5;
lists answer = k * answer1; //here is an error as compiler points
cout << answer;
return 0;
}
I will appreciate your help, I am trying to multiply variable of type my class and double, is it possible?

* is a binary operator, meaning it expects 2 arguments.
When you say a * b, a becomes the first (left) argument and b becomes the second (right) argument. Effectively the function call looks like a.operator*(b).
You are doing, answer1 * k which evaluates to the call answer1.operator*(k) . This means double must have operator* overloaded for lists.
But you want it for your class lists. So you must do this in main():
lists answer = k * answer1;
And operator* must be declared as:
lists lists::operator*(const double& answer)
{
lists k = first * answer; // not sure how double * double equals lists
return k;
}
EDIT:
Regarding the error
lists* lists::var is private within this context
which you pointed out in the comments, it appears because of the inconsistent declaration of friend operator<<.
You have declared it as:
friend std::ostream& operator<<(std::ostream& os, const lists& arg); // note the `const` for `arg`
But you have defined it as:
std::ostream& operator<<(std::ostream& os, lists& arg) // `const` missing!!
{
....
}
Just add const in the definition as well, and it will work as expected.

The line:
lists answer = answer1 * k;
fails because the compiler is looking for a * overload on a double that takes lists instance. This method doesn't exist, but you can define it my creating the method outside your class:
lists operator*(double lhs, const lists &rhs)
{
return lists(lhs) * rhs;
}
NOTE: I've made rhs a const as this is best practice for operator overloads like this which do not (and should not) modify their inputs:
lists operator*(const lists &answer) const;
in the declaration and:
lists lists::operator*(const lists &answer) const
{
lists k = first * answer.first;
return k;
}
in the implementation.
NOTE: I think you meant to multiple by answer.first and otherwise the code doesn't make much sense.
Also, your streaming operator currently tries to output var which is a member variable you never initialize. I suspect you want to output first so change it to this:
std::ostream& operator<<(std::ostream& os, const lists& arg)
{
os << "(" << arg.first << ")";
return os;
}
I've made arg const as this is the recommended practice. You'll need to update your class definition to reflect this.

Related

Using a Friend Operator Assignment and private variable is inaccessible

I am attempting to get the "sum += A" to work in my code I am learning about writing operators but mainly dealt with objects on the left side so because of the sum being a double type I am unsure on how to code my operator to add the value of sum with the balance variable in the bank object and return the sum in the operator.
In my main I have
double sum = 0;
Bank A("Tom", 500.50);
Bank B("Sam", 123.45);
sum += A;
sum += B;
cout << sum << endl;
In my header and implementation file I have
class Bank{
char name[31];
double balance;
public:
friend double operator+=(double, const Bank&);
};
double operator+=(double a, Bank& rhs) {
a += rhs.balance;
return a;
}
I have tried using it without a friend but I am unsure of the correct syntax for having a double value when working with assignment operators. Any help would be appreaicated.
You have a couple of problems.
First - your friend declaration and your method definition don't match (you missed out a const). This means that the method definition is not a friend.
Second - the += operator needs to take its first parameter as a reference, so it can update it. It should also return a reference.
So you should end up with
...
friend double & operator+=(double &, const Bank&);
};
double & operator+=(double &a, const Bank& rhs) {
a += rhs.balance;
return a;
}
In your implementation of operator+=, you are changing a local copy of the variable. It doesn't change the variable in the calling function. You need to use:
double& operator+=(double& a, const Bank& rhs) {
a += rhs.balance;
return a;
}
Also, you need to provide a constructor in Bank to be able to construct instances of the class, something like:
Bank(char const* n, double b) : balance(b)
{
std::strcpy(name, n);
}

Is it possible to overload the ostream operator for arithmetic expressions?

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).

Overriding operator<< for console output doesn't work for member variables

I have a class MyList that overrides the << operator to be able to log itself to the console:
class MyList {
public:
vector<int> *numbers;
};
ostream& operator<<(ostream& os, MyList& l);
Implementation:
ostream& operator<<(ostream& os, MyList& l) {
for (int i = 0; i < l.numbers->size(); i++) {
os << l.numbers->at(i);
}
return os;
}
In an other class I have a member variable of type MyList and I can't print it to the console. Interestingly a local MyList variable works fine:
class A {
public:
MyList list;
void someMethod() const;
};
Implementation:
void A::someMethod() const {
MyList local;
// Set up local list.
cout << "Local:" << local; // OK!
cout << "Member:" << list; // ERROR!
}
This is the error message:
Invalid operands to binary expression ('basic_ostream<char,
std::__1::char_traits<char>>' and 'const MyList')
Xcode's auto-fix recommends to reference list:
cout << "Member:" << &list;
This will compile, but (obviously) it prints the adress of list and not my content. I don't understand what the difference is between those two variables in regards to the << operator. Could anybody explain?
I don't think this is your real code, but here's my guess:
ostream& operator<<(ostream& os, const MyList& l)
// |
// note const
Either that, or something really dumb like forgetting a trailing ;:
class A {
public:
MyList list;
void someMethod();
}; // <------- here
It seems, you omitted a const in several places: As it stands, your code should be OK. However, if you have a const member function, the members are const and you can't bind a non-const reference to a const object. Thus, output operators are normally declared to take a const& as second argument:
std::ostream& operator<< (std::ostream& os, MyList const& l) {
...
}

Operator overloading+ add two objects

I'm trying to add two object that they are in the same class.
In the private section of the class I have two int variables
class One {
private:
int num1, num2;
public:
One operator+=(const One&); // - a member operator that adds another One object - to the current object and returns a copy of the current object
friend bool operator==(const One&, const One&); // - a friend operator that compares two One class objects for equality
};
One operator+(const One&, const One&);// - a non-friend helper operator that adds One objects without changing their values and returns a copy of the resulting One
I'm not sure I have a problem on the opeartor+ I guess
One operator+(const One &a, const One &b){
One c,d,r;
c = a;
d = b;
r += b;
r += a;
return r;
}
I think the above code is wrong, but I tried to use like b.num1 and I get compile error
error: 'int One::num1' is private
error: within this context
and I can't use b->num1 as well because the above function is not in the member function section.
error: base operand of '->' has non-pointer type 'const One'
This is how it calls in main
Result = LeftObject + RightObject;
If you have already implemented this member function:
One One::operator+=(const One&);
Then you may implement the non-member addition operator thus:
One operator+(const One& lhs, const One& rhs) {
One result = lhs;
result += rhs;
return result;
}
This can be simplified somewhat into the following:
One operator+(One lhs, const One& rhs) {
return lhs += rhs;
}
This pattern (which you can adapt for all operator/operator-assignment pairs) declares the operator-assignment version as a member -- it can access the private members. It declares the operator version as a non-friend non-member -- this allows type promotion on either side of the operator.
Aside: The += method should return a reference to *this, not a copy. So its declaration should be: One& operator+(const One&).
EDIT: A working sample program follows.
#include <iostream>
class One {
private:
int num1, num2;
public:
One(int num1, int num2) : num1(num1), num2(num2) {}
One& operator += (const One&);
friend bool operator==(const One&, const One&);
friend std::ostream& operator<<(std::ostream&, const One&);
};
std::ostream&
operator<<(std::ostream& os, const One& rhs) {
return os << "(" << rhs.num1 << "#" << rhs.num2 << ")";
}
One& One::operator+=(const One& rhs) {
num1 += rhs.num1;
num2 += rhs.num2;
return *this;
}
One operator+(One lhs, const One &rhs)
{
return lhs+=rhs;
}
int main () {
One x(1,2), z(3,4);
std::cout << x << " + " << z << " => " << (x+z) << "\n";
}
I can't see why the operator+ is wrong:
#include <stdio.h>
class One {
public:
One(int n1, int n2): num1(n1),num2(n2) {}
private:
int num1, num2;
public:
One operator+=(const One& o) {
num1 += o.num1;
num2 += o.num2;
return *this;
}
friend bool operator==(const One&, const One&); // - a friend operator that compares two One class objects for equality
void print() {
printf("%d,%d\n", num1, num2);
}
};
One operator+(const One& a, const One& b) {
One r(0,0);
r += b;
r += a;
return r;
}
int main() {
One a(1,2),b(3,4);
One r = a + b;
r.print();
}

Multiply a constant to a complex & operator overloading problems

Complex operator*(double m, const
Complex & c)
{ return c * m; }
*On the code above, i'm trying to multiply a constant to a complex number. i receive some errors one of them is [ binary 'operator ' has too many parameters]
ostream & operator<<(ostream & os,
Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
*****Can you tell me what i did wrong on this line as well.
Thanks*****
#include <iostream>
using namespace std;
class Complex
{
private:
double real;
double imaginary;
public:
Complex();
Complex(double r, double i = 0);
Complex operator*(const Complex & c) const;
Complex operator*(double mult) const;
Complex operator*(double m, const Complex & c)
{ return c * m; }
ostream & operator<<(ostream & os, Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
};
Complex::Complex()
{
real = imaginary = 0;
}
Complex::Complex(double r, double i )
{
real = r;
imaginary = i;
}
Complex Complex::operator*(const Complex & c) const
{
Complex mult;
mult.imaginary = imaginary * c.imaginary;
mult.real = real * c.real;
return mult;
}
Complex Complex::operator*(double mult) const
{
Complex result;
result.real = real * mult;
result.imaginary = imaginary * mult;
return result;
}
int main()
{
Complex B(5, 40);
Complex C(6, 15);
cout << "B, and C:\n";
cout << B << ": " << C << endl;
cout << "B * C: " << B*C << endl;
cout << "10 * B: " << 10*B << endl;
return 0;
}
These two operators have problems:
class Complex {
// ...
Complex operator*(double m, const Complex & c)
{return c * m;}
ostream & operator<<(ostream & os, Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
// ...
};
Before anything else: That operator<< isn't supposed to change the complex outputs, so that should be const. (Otherwise you cannot output temporary objects, as they can't be bound to non-const references.)
Since they are non-static member functions, they have an implicit this parameter. With that, they have three parameters. However, both are binary operators. Since you cannot make them static (that's just because the rules say so), you have to implement them as free functions. However, as they are implemented, they need access to private members, so you would have to make them friends of your class:
class Complex {
// ...
friend Complex operator*(double m, const Complex & c);
friend ostream & operator<<(ostream & os, const Complex & c);
// ...
};
Complex operator*(double m, const Complex & c)
{return c * m;}
ostream & operator<<(ostream & os, const Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
On a sidenote, it's possible to implement them inline at the point of the friend declaration, which brings you back almost to your original version:
// note the friend
class Complex {
// ...
friend Complex operator*(double m, const Complex & c)
{return c * m;}
friend ostream & operator<<(ostream & os, const Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
// ...
};
However, if you implement a concrete mathematical type, your type's users will expect all operations common for such types to work with it. That is, they will, for example, expect c*=r to simply work. So you will need to overload operator*=, too. But that operator does almost the same as operator*, so it would be a good idea to implement one on top of the other. A common idiom is to implement *= (and += etc.) as member functions (since they change their left argument, it's a good idea for them to have access to its private data) and operator* as non-member on top of that. (Usually that's more efficient then the other way around.):
// note the friend
class Complex {
// ...
Complex& operator*=(double rhs)
{return /* whatever */;}
friend ostream & operator<<(ostream & os, const Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
// ...
};
inline Complex operator*(Complex lhs, double rhs) // note: lhs passed per copy
{return lhs*=rhs;}
inline Complex operator*(double lhs, const Complex& rhs)
{return rhs*lhs;}
IMO that's the best solution.
I have. however, a few more things to say:
The way you implemented your multiplication is inefficient:
Complex Complex::operator*(const Complex & c) const
{
Complex mult;
mult.imaginary = imaginary * c.imaginary;
mult.real = real * c.real;
return mult;
}
When you say Complex mult;, you invoke the default constructor of your class, which initializes the real and imaginary parts to 0. The next thing you do is to overwrite that value. Why not do it in one step:
Complex Complex::operator*(const Complex & c) const
{
Complex mult(real * c.real, imaginary * c.imaginary);
return mult;
}
or even to more concise
Complex Complex::operator*(const Complex & c) const
{
return Complex(real * c.real, imaginary * c.imaginary);
}
Sure, it's just two assignments per multiplication. But then - you wouldn't want to have this in some inner loop of your graphic driver.
Also, your constructors are not implemented The Way It Ought To be(TM). For initializing member data, you should use the initializer list:
Complex::Complex()
: real(), imaginary()
{
}
Complex::Complex(double r, double i)
: real(r), imaginary(i)
{
}
While it doesn't make any difference for built-in types like double, it doesn't hurt either and it's good to not to get into the habit. With user-defined types (a somewhat unfortunate name, since it is for all non-built-ins, even types like std::string, which isn't defined by users) that have a non-trivial default constructor, it does make a difference: it's far less efficient.
The reason is that, when the execution passes that initial {, C++ guarantees that your data member objects are accessible and usable. For that, they must be constructed, because construction is what turns raw memory into objects. So even if you do not call a constructor explicitly, the run-time system will still call the default constructors. If the next thing you do is overriding the default-constructed values, you're again wasting CPU cycles.
Finally, this constructor Complex(double r, double i = 0) serves as an implicit conversion operator. That is, if, for example, youe meant to call f(real), but forgot to include it, but there is an f(const complex&) in scope, the compiler exercises its right to perform one user-defined conversion and your call f(4.2) becomes f(Complex(4.2)) and the wrong function is silently called. That's very dangerous.
In order to avoid this, you should mark all constructors explicit that could be called with only one argument:
class Complex {
// ...
explicit Complex(double r, double i = 0)
// ...
};
Don't declare Complex operator*(double m, const Complex & c) and the ostream one as member functions (aka methods): declare them as friend functions instead! (If you even need them to be friends, which you wouldn't if you had the obvious inline accessor methods for the imaginary and real parts -- but anyway the point is that they have to be outside the class!).
For member functions, operator* and operator<< only take a single parameter, as the Complex object is already implicitly given, i.e.
c * r
translates to
c.operator*(r)
If you wish to have the two argument form, then an external friend function is what you are looking for. Although, as Alex points out, if you have re and im acessors set up, then your external operators need not be friends.