#include <iostream>
using namespace std;
class ope
{
private: int real, imag;
public:
ope(int r, int i){
real=r;
imag=i;
}
ope operator + (ope const &obj) //operator overloading
{ ope temp;
temp.imag = imag + obj.imag;
temp.real = real + obj.real;
return temp;
}
void show()
{
cout << "Result : " << real << " + i" << imag << endl;//print complex numbers
}
};
int main()
{
ope f1(2,5) , f2(7,6);
ope f3 = f1+f2;
f3.show();
return 0;
}
I am new in programming and I tried to use operator overloading but I got this error can anyone help me? In this code, I am trying to print complex numbers using operator overloading.
The line
ope temp;
requires a parameterless constructor (a.k.a default constructor), but ope has only a constructor that requires two parameters. You might as well use the parameterized constructor here:
ope operator + (ope const &obj) //operator overloading
{
ope temp(real + obj.real, imag + obj.imag);
return temp;
}
... or define a default constructor
class ope {
// ...
public:
ope(): real(0), imag(0) {}
// ...
Related
#include<iostream>
using namespace std;
class Complex {
private:
int real, imag;
public:
Complex(int r = 0, int i = 0) {real = r; imag = i;}
// This is automatically called when '+' is used with
// between two Complex objects
Complex operator + (Complex const &obj) {
Complex res;
res.real = real + obj.real;
res.imag = imag + obj.imag;
return res;
}
void print() { cout << real << " + i" << imag << '\n'; }
};
int main()
{
Complex c1(10, 5), c2(2, 4);
Complex c3 = c1 + c2;
c3.print();
}
Here operator + is overloaded and it is accesing the private member of res class
Some more examples are
ex1 -
struct Edge {
int a,b,w;
};
bool operator<(const Edge& x, const Edge& y) { return x.w < y.w; }
ex2-
#include <bits/stdc++.h>
using namespace std;
struct Edge {
int a,b,w;
bool operator<(const Edge& y) { return w < y.w; }
};
int main() {
int M = 4;
vector<Edge> v;
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.push_back({a,b,w});
}
sort(begin(v),end(v));
for (Edge e: v) cout << e.a << " " << e.b << " " << e.w << "\n";
}
ex1 and ex2 are from the usaco.guide and the first example was from the geeks for geeks
Can anyone explain how it works ?
How here private data members are accessed from the class instance. Can anyone explain how it works ?
First things first, in ex1 and ex2 you're using a struct and so by default every member is public. So any user of the class has access to its members.
Now, even if those data members were private, you've overloaded operator+ and operator< as member functions. And a member function has full access to any(private, public or protected) member of the corresponding class type.
Output of the Program
#include <iostream>
using namespace std;
class Complex {
private:
int real;
int imag;
public:
Complex(int real, int imag);
Complex(Complex& c);
int getreal();
int getimag();
void setreal(int real);
void setimag(int imag);
Complex operator+(Complex c);
~Complex();
};
Complex::Complex(int real = 0, int imag = 0)
{
this->real = real;
this->imag = imag;
}
Complex::Complex(Complex& c)
{
setreal(c.real);
setimag(c.imag);
}
int Complex::getreal()
{
return real;
}
int Complex::getimag()
{
return imag;
}
void Complex::setreal(int real)
{
this->real = real;
}
void Complex::setimag(int imag)
{
this->imag = imag;
}
Complex Complex::operator+(Complex c)
{
Complex temp;
temp.real = real + c.real;
temp.imag = imag + c.imag;
return temp;
}
Complex::~Complex()
{
cout << "Complex Number Class Destroyed" << endl;
}
int main()
{
Complex c1(5, 10), c2(c1), c3;
c3 = c1 + c2;
cout << c3.getreal() << " +i" << c3.getimag() << endl;
return 0;
}
Three destructors are executed for the three objects created in main(): c1, c2 and c3. Two other objects are created in operator+: c and temp.
Sixth object is created if the compiler does not use return value optimization. In this case temp is copied while returning it from operator+.
Why are 6 objects destroyed:
3 of them are you explicitly declared c1,c2,c3 that go out of scope when main ends.
In the operator+ function:
Complex Complex::operator+(Complex c)
{
Complex temp;
...
}
This creates a local 'c' and a local 'temp' - both are destroyed when they go out of scope.(2 more destroys)
I suspect your 6th destructor is because a temp object is returned from this function.
There are ways to avoid most of these copies using the 'rule of three' and references.
#include<iostream>
using namespace std;
class add
{
private: int a,b;
public: add(int x=0)
{
a=x;
}
add operator+(add const &c) // sub operator-(sub const &c)
{ //{
add sum; // sub diff;
sum.a=a+c.a; // diff.a=a-c.a;
return sum; // return diff
} //}
void print()
{
cout<<"sum: "<<a;
}
};
int main()
{
add a1(10),a2(5); //sub s1(10),s2(5);
add a3=a1+a2; // sub s3=s1-s2;
a3.print(); // s3.print();
return 0;
}
Here I've written seperately but what to do if I need to do both in a single code?
I want a C++ code to perform them simultaneously
You can define any reasonable combination of:
Foo operator+(arg);
Foo operator-(arg);
Foo operator*(arg);
Foo operator/(arg);
And the arg can be another Foo or some other type entirely. For instance:
#include <iostream>
using namespace std;
class Operators {
public:
Operators() = default;
Operators(int v) : value(v) {}
Operators operator+(const Operators &other) {
return Operators{value + other.value};
}
Operators operator+(const int byValue) {
return Operators{value + byValue};
}
Operators operator-(const Operators &other) {
return Operators{value - other.value};
}
Operators operator-(const int byValue) {
return Operators{value - byValue};
}
Operators operator*(const Operators &other) {
return Operators{value * other.value};
}
Operators operator/(const Operators &other) {
return Operators{value / other.value};
}
int value = 0;
};
int main(int, char **) {
Operators first{10};
Operators second{20};
Operators result1 = first + second;
Operators result2 = first * second;
Operators result3 = first * 3;
Operators result4 = second / 2;
cout << "first + second == " << result1.value << endl;
cout << "first * second == " << result2.value << endl;
cout << "first * 3 == " << result3.value << endl;
cout << "first / 2 == " << result4.value << endl;
}
first + second == 30
first * second == 200
first * 3 == 30
first / 2 == 10
You'll see I overwrote operators that take two Operators objects, but I also wrote a few that take an integer argument, too.
I compiled and ran that with:
g++ --std=c++17 Whatever.cpp -o Whatever && Whatever
I was trying to make a Complex class which would represent the Complex numbers in c++ but I have encountered an error. The copy constructor seems to be the problem but I am not sure as to what is wrong or why it is wrong. The / operator works well as I return a reference to an object of Complex class. but the * operator does not works when I return an object of Complex class. Please explain this behaviour,
edit: I have used the new operator and a custom copy constructor as it was a requirement of my school to dynamically allocate memory.
here is my code.
#include <iostream>
using namespace std;
class Complex
{
public:
double r, i;
Complex() : r(0), i(0) {}
Complex(int r, int i)
{
this->r = double(r);
this->i = double(i);
}
Complex(double r, int i)
{
this->r = r;
this->i = double(i);
}
Complex(int r, double i)
{
this->r = double(r);
this->i = i;
}
Complex(double r, double i)
{
this->r = r;
this->i = i;
}
Complex(Complex &c)
{
cout<<"cpy constructor called"<<endl;
r = c.r;
i = c.i;
}
void operator()(float r, float i)
{
this->r = r;
this->i = i;
}
void operator()(int r, int i)
{
this->r = r;
this->i = i;
}
Complex operator+(Complex &c)
{
Complex *c1 = new Complex(r + c.r, i + c.i);
return *c1;
}
Complex operator-(Complex &c)
{
Complex *c1 = new Complex(r - c.r, i - c.i);
return *c1;
}
Complex operator*(Complex &c)
{
Complex *c1 = new Complex(
r * c.r + (-1) * (i * c.i),
r * c.i + i * c.r);
return *c1;
}
Complex& operator/(Complex &c)
{
float dem;
Complex num;
num = (*this) * * (new Complex(c.r,-c.i));
dem = c.r*c.r + (c.i*c.i);
Complex *c1 = new Complex(num.r/dem,num.i/dem);
return *c1;
}
operator string()
{
string temp, s;
temp = to_string(r);
while (true)
{
if (temp[temp.length() - 1] == '0')
{
temp.pop_back();
}
else
break;
}
if (temp[temp.length() - 1] == '.')
temp.pop_back();
s += temp;
if (i >= 0)
{
s += '+';
}
temp = to_string(i);
while (true)
{
if (temp[temp.length() - 1] == '0')
{
temp.pop_back();
}
else
break;
}
if (temp[temp.length() - 1] == '.')
temp.pop_back();
s += temp;
s += 'i';
return s;
}
friend ostream &operator<<(ostream &out, Complex c);
};
ostream& operator<<(ostream &out, Complex c)
{
out << string(c);
return out;
}
int main()
{
Complex c(5, 5);
Complex d(5,5);
cout << c/d <<endl;
cout<< c*d <<endl;
}
and this is the error I encounter after this
test.cpp: In function 'int main()':
test.cpp:123:13: error: invalid initialization of non-const reference of type 'Complex&' from an rvalue of type 'Complex'
cout<< c*d <<endl;
~^~
test.cpp:31:5: note: initializing argument 1 of 'Complex::Complex(Complex&)'
Complex(Complex &c)
^~~~~~~
test.cpp:111:10: note: initializing argument 2 of 'std::ostream& operator<<(std::ostream&, Complex)'
ostream& operator<<(ostream &out, Complex c)
This is the image to the error
Repeat the pattern of the code below for your other operators. Note the operator takes the parameter by const ref and returns the result by value:
Complex operator+(Complex const &c)
{
return Complex(r + c.r, i + c.i);
}
The copy constructor should also be changed to take it's parameter by const ref ie
Complex(Complex const &c)
{
r = c.r;
i = c.i;
}
The minimal fix isComplex(Complex &c) -> Complex(const Complex &c)
But then there will remain leaks due to the inappropriate usage of new there, after some cleanup:
#include <iostream>
using namespace std;
class Complex
{
public:
double r, i;
Complex(double r, double i) : r(r), i(i) {}
Complex operator+(Complex c)
{
return Complex(r + c.r, i + c.i);
}
Complex operator-(Complex c)
{
return Complex(r - c.r, i - c.i);
}
Complex operator*(Complex c)
{
return Complex(
r * c.r + (-1) * (i * c.i),
r * c.i + i * c.r);
}
Complex operator/(Complex c)
{
auto num = Complex (*this) * Complex(c.r,-c.i);
auto dem = c.r*c.r + (c.i*c.i);
return Complex(num.r/dem,num.i/dem);
}
operator string()
{
string temp, s;
temp = to_string(r);
while (!temp.empty() && temp.back() == '0')
temp.pop_back();
if (!temp.empty() && temp.back() == '.')
temp.pop_back();
s += temp;
if (i >= 0)
{
s += '+';
}
temp = to_string(i);
while (!temp.empty() && temp.back() == '0')
temp.pop_back();
if (!temp.empty() && temp.back() == '.')
temp.pop_back();
s += temp;
s += 'i';
return s;
}
friend ostream &operator<<(ostream &out, Complex c);
};
ostream& operator<<(ostream &out, Complex c)
{
out << string(c);
return out;
}
int main()
{
Complex c(5, 5);
Complex d(5,5);
cout << c/d <<endl;
cout<< c*d <<endl;
}
The big problem is lack of const on your references and members. The second problem is not using =default. The third problem is too many overloads. Forth, your new use is wrong. operstor() are all wrong. The last problem is your operator strategy. And don't use namespace std;.
struct Complex
Complex is both default public and basically an aggregate. I'd use struct
{
double r=0
double i=0;
you can do default initialization in C++ now.
Complex()=default;
now this ctor is auto-written, because we initialized the members at declaration. DRY is "don't repeat yourself"; when easy, don't repeat member names.
Complex(double r_in, double i_in):r(r_in),i(i_in){}
ctors should construct, not assign, members.
Drop the other 2 arg ctors. Callers can convert.
Complex(Complex const&c)=default;
const here, and let the compiler write a member-wise copy with =default; DRY.
Complex(Complex &&c)=default;
Complex& operator=(Complex const&c)=default;
Complex& operator=(Complex &&c)=default;
also assignment and moves
Now other operators...
Complex& operator+=(Complex const& o)&{
implement a+=b before +.
r+=o.r;
i+=o.i;
return *this;
}
here we repeat member names; it isn't easy to avoid.
Do the same for -= and *=
Next,
friend Complex operator+(Complex lhs, Complex const& rhs){
lhs+=rhs;
return lhs;
}
this makes a non-member +. It makes a copy of its left hand argument by taking it by value, and a const reference to its right hand argument.
We then increment the left hand copy by the right, and return it.
This pattern chans wonderfully in 99% of situations;
Complex x=a+b+c
becomes
Complex x=a;
x+=b;
x+=c;
after accounting for moves and elision.
And you get a+=b; and a+b by writing only one member-wise operation.
Just don't use your operator(), they are nonsense.
I have a class and i keep getting some error from the destructor.
This is the clas:
#pragma once
class Number
{
int bas;
char* val;
public:
Number(const char* value, int base);
Number(const Number& x);
~Number();
void SwitchBase(int newBase);
void Print();
int GetDigitsCount();
int GetBase();
};
This is the cpp file:
#include "Number.h"
#include <iostream>
Number::Number(const char* value, int base)
{
int a = -1;
do
{
a++;
} while (value[a] != '\0');
val = new char[a + 1];
for (int i = 0; i <= a; i++)
val[i] = value[i];
bas = base;
}
Number::Number(const Number& x)
{
int a = -1;
bas = x.bas;
do
{
a++;
} while (x.val[a] != '\0');
delete[]val;
val = new char[a + 1];
int i;
for (i = 0; i <= a; i++)
val[i] = x.val[i];
}
Number::~Number()
{
delete[]val;
}
void Number::Print()
{
std::cout << "Numarul este: " << val<< std::endl << "Baza este: " << bas<<std::endl;
}
int Number:: GetDigitsCount()
{
int l = 0;
do
{
l++;
} while (val[l] != '\0');
return l;
}
This is the main:
int main()
{
Number x("123", 10),y("111",10),z("0",10);
z = y;
z.Print();
}
I keep getting this error:
Invalid address specified to RtlValidateHeap( 010C0000, 010C8DD8 )
If i do this change in main it works properly but it is not really what I want...
int main()
{
Number x("123", 10),y("111",10);
Number z = y;
z.Print();
}
How can I solve this? I can't figure it out...
Your Number class is missing an assignment operator. Since you use the assignment operator in main the default assignment operator will cause a double delete when you exit main and this explains the error.
It also explains why the error goes away when you change main to use the copy constructor instead of the assignment operator.
You should look at the copy and swap idiom to show how to easily and efficiently implement copy constructors and assignment operators.
Alternatively you could also use std::string instead of manually allocating memory. This would eliminate the need to write a destructor, copy constructor and assignment operator. That's the best solution.
This is an example of how code may look like using std::string:
#include <iostream>
#include <string>
class Number
{
int bas;
std::string val;
public:
Number(std::string, int base);
Number(const Number& number);
Number& operator= (const Number& number);
~Number()=default;
void Print();
int GetDigitsCount();
};
Number::Number(std::string value, int base)
{
val=value;
bas=base;
}
Number::Number(const Number& number)
{
val=number.val;
bas=number.bas;
}
Number& Number::operator= (const Number& number)
{
val=number.val;
bas=number.bas;
return *this;
}
void Number::Print()
{
std::cout << "Numarul este: " << val<< std::endl << "Baza este: " << bas<<std::endl;
}
int Number:: GetDigitsCount()
{
return val.size();
}
int main()
{
Number x("123", 10),y("111",10),z("0",10);
Number k(y);
k.Print();
}