I'm attempting to overload a += operator with the following line:
a = b += c += 100.01;
but my second += in that code shows an error as it matches no implementation i guess?
Heres my full relevant code:
main.cpp:
#include <iostream>
#include "Account.h"
using namespace sict;
void displayABC(const Account& a, const Account& b, const Account& c)
{
std::cout << "A: " << a << std::endl << "B: " << b << std::endl
<< "C: " << c << std::endl << "--------" << std::endl;
}
int main()
{
Account a("No Name");
Account b("Saving", 10000.99);
Account c("Checking", 100.99);
displayABC(a, b, c);
a = b + c;
displayABC(a, b, c);
a = "Joint";
displayABC(a, b, c);
a = b += c;
displayABC(a, b, c);
a = b += c += 100.01;
displayABC(a, b, c);
return 0;
}
Account.h (Relevant definitions)
class Account{
public:
friend Account operator+(const Account &p1, const Account &p2);
Account& operator+=(Account& s1);
Account & operator=(const char name[]);
friend double & operator+=(double & Q, Account & A);
Account & operator=(Account D);
};
Account operator+(const Account &p1, const Account &p2);
double operator+=(double& d, const Account& a);
};
Account.cpp (relevant implementations)
Account& Account::operator+=(Account &s1) {
double b = this->balance_ + s1.balance_;
this->balance_ = b;
return *this;
}
Account & Account::operator=(Account D) {
strcpy(name_, D.name_ );
this->balance_ = D.balance_;
return *this;
}
Account & Account::operator=(const char name[])
{
strcpy_s(name_, name);
return *this;
}
double & operator+=(double & Q, Account & A)
{
Q = Q + A.balance_;
return Q;
}
So my question is, how do i change my implementations correctly to run this function: a = b += c += 100.01;
Thank you.
In this statement
a = b += c += 100.01;
at first expression
c += 100.01
is evaluated. However the class does not have a corresponding overloaded operator.
On the other hand if the class has a conversion constructor that converts an object of type double to type Account nevertheless the corresponding operatpr += should be declared like
Account& operator+=(const Account& s1);
^^^^^
Also take into account that these declarations
friend double & operator+=(double & Q, Account & A);
and
double operator+=(double& d, const Account& a);
differ.
Related
I'm new to programming and I have to Overload the += operator , + Operator and ++ post and prefix operator so the following operations work properly but I'm stuck.
Here is the number class:
#include <iostream>
class Number
{
private:
int m_value;
public:
Number(int value = 0);
std::ostream& print(std::ostream& ostr = std::cout)const;
};
std::ostream& operator<<(std::ostream& ostr, const Number& N);
using namespace std;
void prn(const Number& a, const Number& b, const Number& c)
{
cout << "c a b " << endl
<< c << " " << a << " " << b << endl;
cout << "--------------------" << endl;
}
int main()
{
Number a{ 10 }, b{ 20 }, c;
c = a + b;
prn(a, b, c);
c = ++a;
prn(a, b, c);
c = a += b;
prn(a, b, c);
c = b++;
prn(a, b, c);
return 0;
}
/// output:
/*
c a b
30 10 20
--------------------
c a b
11 11 20
--------------------
c a b
31 31 20
--------------------
c a b
20 31 21
----------------
The below program shows how to overload different operator correctly.
#include <iostream>
class Number
{
//overload operator+ so that we can add two Number objects
friend Number operator+(const Number &lhs, const Number &rhs);
//overload operator<< so that we can use std::cout<< c
friend std::ostream& operator<<(std::ostream &os, const Number& num);
int m_value = 0;
public:
Number(int value = 0);
//overload operator+= . This operator will be used inside operator+ definition
Number& operator+=(const Number &rhs);
Number& operator++();
Number operator++(int);
};
Number::Number(int value): m_value(value)
{
}
Number operator+(const Number &lhs, const Number &rhs)
{
Number sum = lhs; // copy data members from lhs into sum
sum += rhs; // add rhs into sum using compound operator
return sum;
}
Number& Number::operator+=(const Number &rhs)
{
m_value += rhs.m_value;
return *this;
}
std::ostream& operator<<(std::ostream &os, const Number& num)
{
os << num.m_value;
return os;
}
Number& Number::operator++()
{
++m_value;
return *this;
}
Number Number::operator++(int)
{
Number old = *this; // copy old value
operator++(); // prefix increment
return old; // return old value
}
void prn(const Number& a, const Number& b, const Number& c)
{
std::cout << "c a b " << std::endl
<< c << " " << a << " " << b << std::endl;
std::cout << "--------------------" << std::endl;
}
int main()
{
Number a{ 10 }, b{ 20 }, c;
c = a + b;
prn(a, b, c);
c = ++a;
prn(a, b, c);
c = a += b;
prn(a, b, c);
c = b++;
prn(a, b, c);
return 0;
}
Now you'll get your desired output as can be seen here.
c a b
30 10 20
--------------------
c a b
11 11 20
--------------------
c a b
31 31 20
--------------------
c a b
20 31 21
--------------------
Having trouble with the overloaded IOstream in my C++ class, the code below is my header file, so there is no main(). The overloaded iostream seems to work with simple cin and cout calls, but when put into more complex ones, it throws no match for operato<< and operator>>.
/*
Provide three constructors Complex(a, b), Complex(a), and Complex(). Complex()
creates a Complex object for number 0 and Complex(a) creates a Complex object with 0 for b.
Also provide the getRealPart() and getImaginaryPart() functions for returning
the real and imaginary part of the complex number, respectively.
*/
/*
Overload the operators +, -, *, /, +=, -=, *=, /=, [ ], unary + and -, prefix ++ and --,
postfix ++ and --, <<, >>. Overload the operators +, -, *, / as nonmember functions.
*/
#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
using namespace std;
class Complex{
public:
Complex();
Complex(double a);
Complex(double a, double b);
void set_I(double input);
void set_R(double input);
double get_I_comp() const; //I accessor
double get_R_comp() const; // double accessor
double getRealPart();
double getImaginaryPart();
Complex operator+(Complex other);
Complex operator+(double other);
Complex operator-(Complex other);
Complex operator-(double other);
Complex operator*(Complex other);
Complex operator*(double other);
Complex operator/(Complex other);
Complex operator/(double other);
void operator++();
Complex& operator++(int dummy);
void operator+=(Complex other);
void operator+=(double other);
void operator-=(Complex other);
void operator-=(double other);
void operator*=(double other);
void operator*=(const Complex& other);
void operator/=(double other);
void operator/=(const Complex& other);
void operator- ();
void operator+ ();
double& operator[](int index);
Complex& operator<<(const int& intput);
Complex& operator>>(const string& output);
friend ostream& operator<<(ostream& out, Complex& target);
friend istream& operator>>(const istream& input, Complex& target);
std::string toString() //temporary solution right now
{
if (this->c_I != 0){
string ret = std::to_string(c_R);
ret = ret + " + ";
ret = ret + std::to_string(c_I);
ret = ret + " i \n";
return ret;
}
else{
string ret = std::to_string(c_R);
return ret;
}
}
Complex& add(double num);
Complex& add(Complex other);
Complex& subtract(double num);
Complex& subtract(Complex other);
Complex& multiply(double num);
Complex& multiply(Complex other);
Complex& divide(double num);
Complex& divide(Complex other);
Complex& abs();
private:
double c_I;
double c_R;
};
Complex::Complex() : c_I(0),c_R(0){ //works
}
Complex::Complex(double a) :c_I(0),c_R(a){ //works
}
Complex::Complex(double a, double b){ //works // at first I have the i as a and r as b, so thats why is fliped
this->c_I = b;
this->c_R = a;
}
double Complex::get_I_comp() const{
return c_I;
}
double Complex::get_R_comp() const{
return c_R;
}
double Complex::getImaginaryPart(){
return c_I;
}
double Complex::getRealPart(){
return c_R;
}
void Complex::set_I(double input){
c_I = input;
}
void Complex::set_R(double input){
c_R = input;
}
Complex Complex::operator+(Complex other){
Complex ret( (this->c_R + other.get_R_comp() ),(this->c_I + other.get_I_comp()));
return (ret);
}
Complex Complex::operator+(double other){
Complex ret(this->c_R + other,this->c_I);
return ret;
}
Complex Complex::operator-(Complex other){
Complex ret(this->c_R - other.get_R_comp(),this->c_I - other.get_I_comp());
return ret;
}
Complex Complex::operator-(double other){
Complex ret(this->c_R - other,this->c_I);
return ret;
}
Complex Complex::operator*(double other){
Complex ret(this->c_R * other ,this->c_I *other);
return ret;
}
Complex Complex::operator*(Complex other){
if((other.get_I_comp() != 0) && (other.get_R_comp() != 0) ){
Complex ret = other * (this->c_R);
Complex neu(-(other.get_I_comp()*this->c_I),other.get_R_comp()*this->c_I);
return (ret + neu);
}
if((other.get_I_comp() == 0 ) && (other.get_R_comp() != 0)){
Complex ret(this->c_R,this->c_I);
ret = ret * other.get_R_comp();
return ret;
}
else{
Complex ret((-((this->c_I)*other.get_I_comp())),(this->c_R)*other.get_I_comp());
return ret;
}
}
Complex Complex::operator/(double other){
if (other == 0) { // zero division error handler
throw runtime_error("Math error: Can't div by zero\n");
return 1;
}
if(other != 0){
Complex ret(this->c_R/other,this->c_I/other);
return ret;
}
}
//To divide a+bi by c+id we will perform the operation (ac+bd)/(c^2 + d^2) + (bc-ad)/(c^2 + d^2)i.
Complex Complex::operator/(Complex other){
if ((other.get_I_comp() != 0) && (other.get_R_comp() != 0)){
double first = ((this->c_R)*other.get_R_comp() + (this->c_I)*other.get_I_comp())/(other.get_R_comp()*other.get_R_comp() + other.get_R_comp()*other.get_R_comp());
double second = (this->c_I*other.get_R_comp() + c_R*other.get_I_comp())/(other.get_R_comp()*other.get_R_comp() + other.get_I_comp()*other.get_I_comp());
Complex ret(first,second);
return ret;
}
if((other.get_I_comp() == 0 ) && (other.get_R_comp() != 0)){
Complex ret(this->c_R,this->c_I);
ret = ret *(1/other.get_R_comp());
return ret;
}
else{
Complex ret(this->c_R,this->c_I);
Complex neu(1/other.get_I_comp());
ret = ret * neu;
return ret;
}
}
void Complex::operator++(){
c_R++;
}
Complex& Complex::operator++(int dummy){
Complex temp = *this;
++temp;
c_R++;
return temp;
}
void Complex::operator+=(double other){
c_R += other;
}
void Complex::operator+=(Complex other){
c_R += other.get_R_comp();
c_I += other.get_I_comp();
}
void Complex::operator-=(double other){
c_R +=(-1*other);
}
void Complex::operator-=(Complex other){
c_R -= other.get_R_comp();
c_I -= other.get_I_comp();
}
void Complex::operator*=(double other){
Complex& reference = *this; //pass by reference editing
reference = reference* other;
}
void Complex::operator*=(const Complex& rhs){
Complex& reference = *this;
reference = reference * rhs;
}
void Complex::operator/=(double other){
Complex& reference = *this;
reference = reference / other;
}
void Complex::operator/=(const Complex& rhs){
Complex& reference = *this;
reference = reference / rhs;
}
double& Complex::operator[](int index){
if(index <= 1){
return(index == 0 ? c_R : c_I);
}
else{
throw std::out_of_range ("index outta bound");
}
}
void Complex::operator-(){
c_R*=(-1);
c_I*=(-1);
}
void Complex::operator+(){
if(c_R<0){
c_R*=(-1);
}
if(c_I<0){
c_I*=(-1);
}
}
Complex& Complex::add(double num){
Complex& reference = *this;
reference = reference + num;
return reference;
}
Complex& Complex::add(Complex other){
Complex& reference = *this;
reference = reference + other;
return reference;
}
Complex& Complex::subtract(double num){
Complex& reference = *this;
reference = reference - num;
return reference;
}
Complex& Complex::subtract(Complex other){
Complex& reference = *this;
reference = reference - other;
return reference;
}
Complex& Complex::multiply(double num){
Complex& reference = *this;
reference = reference*num;
return reference;
}
Complex& Complex::multiply(Complex other){
Complex& reference = *this;
reference = reference * other;
return reference;
}
Complex& Complex::divide(double num){
Complex& reference = *this;
reference = reference/num;
return reference;
}
Complex& Complex::divide(Complex other){
Complex& reference = *this;
reference = reference/other;
return reference;
}
Complex& Complex::abs(){
Complex& reference = *this;
+reference;
return reference;
}
ostream& operator<<(ostream& out, Complex& target){
out << "Real : ";
out << " " << target.getRealPart();
out << " imaginary :";
out <<target.getImaginaryPart();
return out;
}
istream& operator>>(const istream& input, Complex& target) {
string use;
input>>use;
stringstream convert(use);
int x = 0;
convert>>x;
target.set_R(x);
return input;
}
when doing calls such as
cout << "(" << number1 << ")" << " + " << "(" << number2 << ") = " << (number1 + number2) << endl;
it throws the following exception:
main.cpp:19:69: error: no match for ‘operator<<’ (operand types are ‘std::basic_ostream’ and ‘Complex’)
cout << "(" << number1 << ")" << " + " << "(" << number2 << ") = " << (number1 + number2) << endl;
In file included from main.cpp:1:0:
Complex.h:276:10: note: candidate: std::ostream& operator<<(std::ostream&, Complex&)
ostream& operator<<(ostream& out, Complex& target){
You have to overload the following function too!.
ostream& operator<<(ostream& out, Complex&& target){
out << "Real : ";
out << " " << target.getRealPart();
out << " imaginary :";
out <<target.getImaginaryPart();
return out;
}
Non-const references don't bind to temporaries.
So ostream& operator<<(ostream& out, Complex& target) can't be used in code that looks like cout << Complex{1.0} or cout << (complex1 + complex2), because in both cases the second argument is a temporary Complex instance.
A possible fix is to use const references when you don't plan to modify the argument:
ostream& operator<<(ostream& out, Complex const& target)
Another solution (for small objects) is to accept it by-value:
ostream& operator<<(ostream& out, Complex target)
Given the following code:
#include <iostream>
using namespace std;
class B {
private:
int n;
public:
B(int x) :
n(x) {
}
B operator+(B& b) {
return B(n + b.n);
}
friend ostream& operator<<(ostream &out, const B& b) {
out << "B: " << b.n;
return out;
}
bool operator<(const B& rhs) const {
return n < rhs.n;
}
};
int main() {
B b1(1), b2(2), b3(3);
const B b4 = b1 + (b2 + b3); // error
cout << b4 << b1 << b2 << b3;
return 0;
}
I know that if I will change this :
B operator+(B& b)
To:
B operator+(const B& b)
So it's will be ok. But, why it's really fix it?
invalid initialization of non-const reference of type 'B&' from an rvalue of type 'B'
(I understand the meaning of the error, but, I don't understand why the changing fix the error).
In addition, what is the difference between the code above (that give me error), to the following code:
class D: public B {
double m;
public:
D() :
B(0), m(0) {
}
D(int x, int y) :
B(x), m(y) {
}
D operator+(D& d) { // ~~
return d;
}
friend ostream& operator<<(ostream &out, const D& d) {
out << static_cast<const B&>(d);
out << ", D: " << d.m;
return out;
}
};
int main() {
B b4(4);
D d1(1, 0), d2(1, 2);
D d3 = d1 + d2;
cout << b4 << ", " << d3 << endl;
return 0;
}
Why now I don't get at ~~ also error?
This question already has answers here:
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 5 years ago.
can i add three objects using operator overloading in c++??
#include <iostream>
#include <conio.h>
using namespace std;
class complex{
private:
int a;
public:
void setdata(int x){
a=x;
}
void showdata(){
cout<<"\n"<<a;
}
int operator +(complex c,complex d){
complex temp;
temp.a=a+c.a+c+d.a;
return (temp);
}
};
int main(){
complex c1,c2,c3,c4;
c1.setdata(3);
c2.setdata(5);
c4.setdata(2);
c4=c1+c2+c3;
c4.showdata();
}
i am using this approach but it is not working please help.
you have to change a little the operator and you have a mistake in the inizialization of the variables (C3 is not initialized).
You have not to define an operator that works on three terms at the same time. The sum will be split in two parts (c1 + c2) + c3; the first sum returns a 'complex' item that is added to c3. The result of this last sum is assigned to c4.
See below the code.
#include <iostream>
#include <conio.h>
using namespace std;
class complex{
private:
int a;
public:
void setdata(int x){
a = x;
}
void showdata(){
cout << "\n" << a;
}
complex operator +(complex c){
complex temp;
int i = 0;
i = a + c.a;
temp.setdata(i);
return temp;
}
};
int main(){
complex c1, c2, c3, c4;
c1.setdata(3);
c2.setdata(5);
c3.setdata(2);
c4 = c1 + c2 + c3;
c4.showdata();
}
In my comments, I suggested two alternative solutions but while fiddling around with the sample code I even found a third one.
The sample code:
#include <iostream>
// Version 1: (return type fixed)
class Complex1 {
friend std::ostream& operator << (std::ostream &out, const Complex1 &c);
private:
int a;
public:
explicit Complex1(int a): a(a) { }
// operator + as member
Complex1 operator + (const Complex1 &c) const
{
return Complex1(a + c.a);
}
};
std::ostream& operator << (std::ostream &out, const Complex1 &c)
{
return out << c.a;
}
// Version 2: (two overloaded operators)
class Complex2 {
friend std::ostream& operator << (std::ostream &out, const Complex2 &c);
friend int operator+(const Complex2 &c, const Complex2 &d);
friend int operator+(int c, const Complex2 &d);
private:
int a;
public:
explicit Complex2(int a): a(a) { }
};
std::ostream& operator << (std::ostream &out, const Complex2 &c)
{
return out << c.a;
}
int operator+(const Complex2 &c, const Complex2 &d)
{
return c.a + d.a;
}
int operator+(int c, const Complex2 &d)
{
return c + d.a;
}
// Version 3: (implicit conversion with constructor)
class Complex3 {
friend std::ostream& operator << (std::ostream &out, const Complex3 &c);
private:
int a;
public:
Complex3(int a): a(a) { }
// operator + as member
int operator+(const Complex3 &c) const
{
return a + c.a;
}
};
std::ostream& operator << (std::ostream &out, const Complex3 &c)
{
return out << c.a;
}
// Check everything out:
using namespace std;
int main()
{
cout << "Version 1:" << endl;
{ Complex1 c1(3), c2(5), c3(2);
Complex1 c4 = c1 + c2 + c3;
cout << "c4: " << c4 << endl;
}
cout << "Version 2:" << endl;
{ Complex2 c1(3), c2(5), c3(2);
Complex2 c4 = Complex2(c1 + c2 + c3);
cout << "c4: " << c4 << endl;
}
cout << "Version 3:" << endl;
{ Complex1 c1(3), c2(5), c3(2);
Complex1 c4 = c1 + c2 + c3;
cout << "c4: " << c4 << endl;
}
cout << "done." << endl;
return 0;
}
You may compile and run the code on ideone.
Complex1 provides a fixed operator as member
Complex1 Complex1::operator + (const Complex1 &c) const;
Hence, (c1 + c2) + c3 is
(Complex1 × Complex1 → Complex1) × Complex1 → Complex1
Complex2 provides two overloaded operators as non-members
int operator+(const Complex2 &c, const Complex2 &d);
int operator+(int c, const Complex2 &d);
Hence, c1 + c2 is
Complex2 × Complex2 → int
and (c1 + c2) + c3 is
int × Complex2 → int
Complex3 is very similar like the original sample with the essential difference that I provided a non-explicit constructor which accepts an int. This means the compiler will use it as conversion operator when necessary.
(With a proper constructor, the operator issue probably hadn't been noticed soon.)
Thus, c1 + c2 is
Complex3 × Complex3 → int
and (c1 + c2) + c3 is
(int → Complex3) × Complex3 → int
I am trying to create a function that conjugate a complex number
for example A(2, 3) will turn into A(2,-3) by typing ~A
i have done a little code below but i guess it's wrong, i hope you can help me slove this.
i have quoted the part that i did wrong in the code below.
#include <iostream>
using namespace std;
class Complex
{
private:
double real;
double imaginenary;
public:
Complex();
Complex(double r, double i = 0);
// Declaration
Complex operator~(const Complex & c) const;
Complex operator+(const Complex & c) const;
Complex operator-(const Complex & c) const;
Complex operator*(const Complex & c) const;
Complex operator*(double n) const;
friend Complex operator*(double m, const Complex & c)
{ return c * m; }
friend ostream & operator<<(ostream & os, const Complex & c);
};
Complex::Complex()
{
real = imaginenary = 0;
}
Complex::Complex(double r, double i )
{
real = r;
imaginenary = i;
}
// Definition
Complex Complex::operator~(const Complex & c) const
{
Complex conj;
conj.imaginenary = -1 * imaginenary;
conj.real = real;
}
Complex Complex::operator+(const Complex & c) const
{
Complex sum;
sum.imaginenary = imaginenary + c.imaginenary;
sum.real = real + c.real;
return sum;
}
Complex Complex::operator-(const Complex & c) const
{
Complex diff;
diff.imaginenary = imaginenary - c.imaginenary;
diff.real = real - c.real;
return diff;
}
Complex Complex::operator*(const Complex & c) const
{
Complex mult;
mult.imaginenary = imaginenary * c.imaginenary;
mult.real = real * c.real;
return mult;
}
Complex Complex::operator*(double mult) const
{
Complex result;
result.real = real * mult;
result.imaginenary = imaginenary * mult;
return result;
}
ostream & operator<<(ostream & os, const Complex & c)
{
os << "(" << c.real <<"," << c.imaginenary<<"i)";
return os;
}
int main()
{
Complex A;
Complex B(5, 40);
Complex C(2, 55);
cout << "A, B, and C:\n";
cout << A <<"; " << B << ": " << C << endl;
cout << " complex conjugate is" << ~C << endl;
cout << "B + C: " << B+C << endl;
cout << "B * C: " << B*C << endl;
cout << "10 * B: " << 10*B << endl;
cout << "B - C: " << B - C << endl;
return 0;
}
The tilde (~) operator is a unary operator so it shouldn't accept a parameter (it works on *this). You also forgot to return a value from operator~.
Complex operator~() const
{
return Complex( real, -1 * imaginenary);
}
See your fixed code here
BTW: It's spelt imaginary.
try
Complex Complex::operator~() const
{
Complex conj;
conj.imaginenary = -1 * imaginenary;
conj.real = real;
return conj;
}
But it might be wiser to remove the operators from the class definition and create (friend) functions instead. It works better with implicit type conversion.
Lots of code, but if you would have compared your operator~ to e.g. operator+ , you would have spotted one detail - there's no return statement.
Complex Complex::operator~(const Complex & c) const
{
Complex conj;
conj.imaginenary = -1 * c.imaginenary;
conj.real = c.real;
return conj;
}
This should do.
Although it's not the best idea to return anything you've allocated inside nonglobal scope, since that region in the memory can be overwritten anytime. And btw it's imaginary, not imaginenary :)
friend Complex operator*(double m, const Complex & c) { return c * m; }
friend ostream & operator<<(ostream & os, const Complex & c);
Is there anyway to avoid using friend in this problem? because i have read that from the book but not quite understand it.