Using a Friend Operator Assignment and private variable is inaccessible - c++

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);
}

Related

How do overload an assignment operator that sums two instance variable of a class?

The detailed discussion of the problem is shown in this link. I am trying to sum up two instance variable defined inside class Point and assign it to a different variable temp.
class Point{
public:
double x;
double y;
friend istream& operator>>(istream& input, Point& p);
double operator=(Point& p);
double getSqX(void);
double getSqY(void);
double LengthSquared(void);
};
double Point::getSqX(void){
return pow(x,2);}
double Point::getSqY(void){
return pow(y,2);}
double Point::LengthSquared(){ return getSqX() + getSqY(); }
istream& operator>>(istream& input, Point& p){
... // over load the >> operator
return input;
};
int main(){
double temp;
vector<vector<Point> > FFTfile= some function that loads data();
for (int i = 0; i < FFTfile.size(); i++){
for (int j = 0; j < FFTfile[i].size(); j++){
temp=FFTfile[j].LengthSquared();
}
}
return(0);
}
Edit:
Based on the suggestions, I created a method LengthSquared(), but I still get following error:
error: 'class std::vector<Point>' has no member named 'LengthSquared' temp=FFTfile[j].LengthSquared();
You should never overload the assignment operator this way. Someone reading your code will be confused, since assignment normally means .. assign value to object.
Instead, create a method like this
double Point::LengthSquared() { return getSqX() + getSqY(); }
an assignment-operator should have the following interface:
Point& operator=(const Point& other);
or
Point& operator=(const AnotherType& other);
to allow assignments of other types.
You are abusing the assignment operator. Use a regular method.

Overloading operators outside of the class

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.

Overloading Operators

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.

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

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();
}