I have so big problem. I write a program which is about complex numbers. This program read and write complex numbers, add them, etc.
He said that I should read that Why should I overload a C++ operator as a global function (STL does) and what are the caveats? and
1) I must create 5 operators which are member function of class and which have one argument: +, −, !, ++, −−. Then
2) I must create 5 operators which are member function of class and which two arguments: =,+=, −=, *=, /=; Then
3) I must create 8 operators which are global friend function +, −, *, /, ==, !=, <<, >> and take two parameters. I have no problem with the last one:
friend const Comp operator+(const Comp& x, const Comp& y)
{
Comp temp;
temp.real = x.real + y.real;
temp.imag = x.imag + y.imag;
return temp;
}
friend const Comp operator-(const Comp& x, const Comp& y)
{
Comp temp;
temp.real = x.real - y.real;
temp.imag = x.imag - y.imag;
return temp;
}
friend const Comp operator*(const Comp& x, const Comp& y)
{
Comp temp;
temp.real = x.real * y.real;
temp.imag = x.imag * y.imag;
return temp;
}
friend const Comp operator/(const Comp& x, const Comp& y)
{
Comp temp;
temp.real = x.real / y.real;
temp.imag = x.imag / y.imag;
return temp;
}
except this?????? What I should return here????? When I compare It should be bool yeah????
friend const Comp operator==(const Comp& x, const Comp& y)
{
}
friend const Comp operator!=(const Comp& x, const Comp& y)
{
}
I think that I found solution
friend bool operator==(const Comp& x, const Comp& y)
{
return (x.real == y.real && x.imag == y.imag);
}
friend bool operator!=(const Comp& x, const Comp& y)
{
return (x.real != y.real && x.imag != y.imag);
}
This is my whole code
#include <fstream>
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <cmath>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
using namespace std;
class Comp {
double real, imag;
public:
Comp(){
real;
imag;
}
double re(void) const
{
return real;
}
double im(void) const
{
return imag;
}
double mod(void) const
{
return sqrt(re()*re() + im()*im());
}
double arg(void) const
{
double faza;
if (im() >= 0)
faza = acos(re()/mod());
else
faza = 2*M_PI - acos(re()/mod());
return faza;
}
const Comp conj(void) const
{
Comp temp;
-im();
return temp;
}
~Comp(){}
/*
Comp operator+(const Comp& x);
Comp operator-(const Comp& x);
bool operator!(void);
const Comp& operator++();
const Comp operator++(int);
const Comp& operator--();
const Comp operator--(int);
Comp operator=(const Comp x);
Comp operator-=(const Comp& x);
Comp operator+=(const Comp& x);
Comp operator*=(const Comp& x);
Comp operator/=(const Comp& x);
*/
friend const Comp operator+(const Comp& x, const Comp& y)
{
Comp temp;
temp.real = x.real + y.real;
temp.imag = x.imag + y.imag;
return temp;
}
friend const Comp operator-(const Comp& x, const Comp& y)
{
Comp temp;
temp.real = x.real - y.real;
temp.imag = x.imag - y.imag;
return temp;
}
friend const Comp operator*(const Comp& x, const Comp& y)
{
Comp temp;
temp.real = x.real * y.real;
temp.imag = x.imag * y.imag;
return temp;
}
friend const Comp operator/(const Comp& x, const Comp& y)
{
Comp temp;
temp.real = x.real / y.real;
temp.imag = x.imag / y.imag;
return temp;
}
friend const Comp operator==(const Comp& x, const Comp& y)
{
Comp temp;
temp.real = x.real + y.real;
temp.imag = x.imag + y.imag;
return temp;
}
friend const Comp operator!=(const Comp& x, const Comp& y)
{
Comp temp;
temp.real = x.real + y.real;
temp.imag = x.imag + y.imag;
return temp;
}
friend std::ostream& operator<<(std::ostream& wart1, const Comp& a)
{
return wart1 <<fixed << setprecision(2) << '(' << a.re() << "," << a.im() << ')' << ' ' << endl;
}
friend std::istream& operator>>(std::istream& wart2, Comp& b){
char c;
return wart2>>c>>b.real>>c>>b.imag>>c;
}
};
int main(int argc, char* argv[])
{
ifstream read(argv[1]);
if (!read)
{ cerr << "Open error: " << argv[1] << endl; exit(1);}
ofstream write(argv[2]);
if(!write) { cerr << "Open error: " << argv[2] << endl; exit(2);}
read.clear();
read.seekg(0);
Comp x1;
read >> x1;
write << x1;
cout << x1;
Comp x2;
read >> x2;
write << x2;
cout << x2;
cout << x1.mod() << endl;
cout << x2.mod() << endl;
cout << x1.arg() << endl;
cout << x2.arg() << endl;
cout << x1.conj();
cout << x2.conj();
write << x2;
write << x1.mod() << endl;
write << x2.mod() << endl;
write << x1.arg() << endl;
write << x2.arg() << endl;
write << x1.conj();
write << x2.conj();
Comp sum;
sum = x1 + x2;
cout << sum;
write << sum;
Comp sub;
sub = x1 - x2;
cout << sub;
write << sub;
Comp mult;
mult = x1 * x2;
cout << mult;
write << mult;
Comp div;
div = x1 / x2;
cout << div;
write << div;
return 0;
}
If you implement operator== correctly (which you did in your block titled "I think that I found solution"), then you can leverage it for operator!=:
friend bool operator!=(const Comp& x, const Comp& y)
{
return !(x == y);
}
Your version was incorrect since it would report that they are not unequal if they had the same real part and a different imaginary part.
Also, in part (1) it refers to unary + and - (not binary versions which we get in part 3). So your first two declarations in the commented-out block are incorrect, they should be:
Comp operator+();
Comp operator-();
Related
I would like to calculate the sum of squares complex numbers in descending order by using three source codes(Complex2.h, Complex2.cpp, Vector3)
ex) (5+6i)^2 (3+4i)^2 (1+2i)^2....
I'm trying to add and change some codes in Vector3 to get the result, but stuck in the middle now..
Does anyone give some advice?
//Complex2.h
#ifndef COMPLEX2_H_INCLUDED
#define COMPLEX2_H_INCLUDED
#include <ostream>
using namespace std;
class Complex2 {
double rPart, iPart; // real part and imaginary part
public:
// operator
Complex2(double r = 0, double i = 0) : rPart(r), iPart(i) {}
Complex2 conj() const {
return Complex2(rPart, -iPart);
}
Complex2 operator+(const Complex2 &c) const;
Complex2 operator+(double r) const;
Complex2 operator-(const Complex2 &c) const;
Complex2 operator-(double r) const;
Complex2 operator*(const Complex2 &c) const;
Complex2 operator*(double r) const;
Complex2 operator/(const Complex2 &c) const;
Complex2 operator/(double r) const;
Complex2& operator+=(const Complex2 &c);
Complex2& operator-=(const Complex2 &c);
Complex2& operator*=(const Complex2 &c);
Complex2& operator/=(const Complex2 &c);
bool operator==(const Complex2 &c) const;
bool operator!=(const Complex2 &c) const;
double real() const { return rPart; }
double imag() const { return iPart; }
void display() const; // print complex value
friend Complex2 operator+(double r, const Complex2& c);
friend ostream& operator<<(ostream& os, const Complex2& c);
};
#endif
//Complex2.cpp
#include <iostream>
#include "Complex2.h"
using namespace std;
Complex2 Complex2::operator+(const Complex2 &c) const
{
return Complex2(rPart + c.rPart, iPart + c.iPart);
}
Complex2 Complex2::operator+(double r) const
{
return Complex2(rPart + r, iPart);
}
Complex2 Complex2::operator-(const Complex2 &c) const
{
return Complex2(rPart - c.rPart, iPart - c.iPart);
}
Complex2 Complex2::operator-(double r) const
{
return Complex2(rPart - r, iPart);
}
Complex2 Complex2::operator*(const Complex2 &c) const
{
return Complex2(rPart * c.rPart - iPart * c.iPart, rPart * c.iPart + iPart * c.rPart);
}
Complex2 Complex2::operator*(double r) const
{
return Complex2(rPart * r, iPart * r);
}
Complex2 Complex2::operator/(const Complex2 &c) const
{
double d = c.rPart * c.rPart + c.iPart * c.iPart;
return Complex2((rPart * c.rPart + iPart * c.iPart) / d, (iPart * c.rPart - rPart * c.iPart) / d);
}
Complex2 Complex2::operator/(double r) const
{
return Complex2(rPart / r, iPart / r);
}
Complex2& Complex2::operator+=(const Complex2 &c)
{
rPart += c.rPart; iPart += c.iPart;
return *this;
}
Complex2& Complex2::operator-=(const Complex2 &c)
{
rPart -= c.rPart; iPart -= c.iPart;
return *this;
}
Complex2& Complex2::operator*=(const Complex2 &c)
{
*this = *this * c;
return *this;
}
Complex2& Complex2::operator/=(const Complex2 &c)
{
*this = *this / c;
return *this;
}
bool Complex2::operator==(const Complex2 &c) const
{
return rPart == c.rPart && iPart == c.iPart;
}
bool Complex2::operator!=(const Complex2 &c) const
{
return rPart != c.rPart || iPart != c.iPart;
}
void Complex2::display() const
{
cout << "(" << rPart;
if (iPart > 0)
cout << "+j" << iPart;
else if (iPart < 0)
cout << "-j" << -iPart;
cout << ")";
}
Complex2 operator+(double r, const Complex2& c)
{
return Complex2(r + c.rPart, c.iPart);
}
ostream& operator<<(ostream& os, const Complex2& c)
{
os << "(" << c.rPart; // print real part
if (c.iPart > 0) // print imaginary part
os << "+j" << c.iPart;
else if (c.iPart < 0)
os << "-j" << -c.iPart;
cout << ")";
return os;
}
//Vector3.cpp
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include "Complex2.h";
using namespace std;
template<typename T> struct GREATER {
bool operator()(const T& a, const T& b) const {
return a > b;
}
};
int main()
{
srand((unsigned)time(NULL)); // Initialize random number generation
vector<Complex2> cv1(5);
cout << "vector1 : ";
for (auto &c : cv1) {
c = rand() % 100; // 0~99 random number generation
cout << c << " ";
}
sort(cv1.begin(), cv1.end(), GREATER<int>()); // sort algorithm in descending
cout << endl << "sorted vector1 : ";
for (auto c : cv1)
cout << c << " ";
cout << endl << endl;
vector<Complex2> cv2(5);
cout << "vector2 : ";
for (auto &c : cv2) {
c = rand() % 100; // 0~99 random number generation
cout << c << " ";
}
sort(cv2.begin(), cv2.end(), GREATER<int>()); // sort algorithm in descending
cout << endl << "sorted vector2 : ";
for (auto c : cv2)
cout << c << " ";
cout << endl << endl;
// vector for saving the merged result
vector<Complex2> cv3(cv1.size() + cv2.size());
// Save the result cv1 plus cv2 as cv3
merge(cv1.begin(), cv1.end(),
cv2.begin(), cv2.end(), cv3.begin(), GREATER<int>());
cout << "the result of merged vector1 and vector2 : ";
for (auto c : cv3)
cout << c << " ";
cout << endl << endl;
return 0;
}
To do this, all you actually need is to define operator>:
bool Complex2::operator>(const Complex2 &c) const
{
return rPart * rPart + iPart * iPart > c.rPart * c.rPart + c.iPart * c.iPart;
}
Then you can call std::sort and std::merge with:
std::sort(cv1.begin(), cv1.end(), std::greater<Complex2>());
std::merge(cv1.begin(), cv1.end(), cv2.begin(), cv2.end(),
cv3.begin(), std::greater<Complex2>());
Side note: why not use std::complex?
One thing which is very important here:
It is impossible to order complex numbers!!!
You are talking about ordering them, and you seem to be looking for some ordering function, but you need to know that, whatever the means of ordering complex numbers, the ordering must satisfy following argument:
Order(Number1, Number2) AND Order(Number2, Number3) => Order(Number1, Number3)
This expression can't be true, for any kind of ordering you might be inventing (at least for complex numbers, for real numbers ordering is simple), so your question about "descending order" of complex numbers cannot make sense.
The whole explanation can be found here.
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)
I have this formatted string in an istream.
(5, -4)
Let say :
open parenthesis
an integer number
comma and space
another integer number
close parenthesis
I would like to know what is the best approach to extract both integers and validate the string formatting.
This is in a class like this :
class MyPoint
{
public:
MyPoint() = default;
~MyPoint() = default;
...
friend ostream & operator>>(ostream & lhs, MyPoint const & rhs);
...
private:
int x, y;
};
ostream & operator>>(ostream & lhs, MyPoint const & rhs) {
// ???
}
Many thanks to all.
Here is my header file
#ifndef MYPOINT_H
#define MYPOINT_H
#include <iostream>
using namespace std;
class MyPoint
{
public:
MyPoint() : mX{ 0 }, mY{ 0 } { ; }
MyPoint(int x, int y) : mX{ x }, mY{ y } { ; }
~MyPoint() = default;
int x() const { return mX; }
int y() const { return mY; }
void setX(int x) { mX = x; }
void setY(int y) { mY = y; }
MyPoint operator-() const { return MyPoint(-mX, mY); }
MyPoint operator+(MyPoint rhs) const { rhs.mX += mX; rhs.mY += mY; return rhs; }
MyPoint operator-(MyPoint rhs) const { rhs.mX = mX - rhs.mX; rhs.mY = mY - rhs.mY; return rhs; }
MyPoint operator*(MyPoint rhs) const { rhs.mX *= mX; rhs.mY *= mY; return rhs; }
MyPoint operator/(MyPoint rhs) const { rhs.mX = mX / rhs.mX; rhs.mY = mY / rhs.mY; return rhs; }
MyPoint operator%(MyPoint rhs) const { rhs.mX = mX % rhs.mX; rhs.mY = mY % rhs.mY; return rhs; }
friend MyPoint operator+(int lhs, MyPoint const & rhs);
friend MyPoint operator-(int lhs, MyPoint const & rhs);
friend MyPoint operator*(int lhs, MyPoint const & rhs);
friend MyPoint operator/(int lhs, MyPoint const & rhs);
friend MyPoint operator%(int lhs, MyPoint const & rhs);
friend ostream & operator<<(ostream & lhs, MyPoint const & rhs);
friend istream & operator>>(istream & lhs, MyPoint & rhs);
private:
int mX, mY;
};
#endif //MYPOINT_H
And here my source file
#include "MyPoint.h"
MyPoint operator+(int lhs, MyPoint const & rhs) {
return MyPoint(lhs + rhs.mX, lhs + rhs.mY);
}
MyPoint operator-(int lhs, MyPoint const & rhs) {
return MyPoint(lhs - rhs.mX, lhs - rhs.mY);
}
MyPoint operator*(int lhs, MyPoint const & rhs) {
return MyPoint(lhs * rhs.mX, lhs * rhs.mY);
}
MyPoint operator/(int lhs, MyPoint const & rhs) {
return MyPoint(lhs / rhs.mX, lhs / rhs.mY);
}
MyPoint operator%(int lhs, MyPoint const & rhs) {
return MyPoint(lhs % rhs.mX, lhs % rhs.mY);
}
ostream & operator<<(ostream & lhs, MyPoint const & rhs) {
return lhs << "(" << rhs.mX << "," << rhs.mY << ")";
}
istream & operator >> (istream & lhs, MyPoint & rhs) {
return lhs >> "(" >> rhs.mX >> "," >> rhs.mY >> ")"; // HERE is the compiling error
}
And finally, the tests in the main
MyPoint p1, p2(2, -2);
cout << p1 << endl;
cout << p2 << endl;
With this file, I got this error :
Error C2679 binary '>>': no operator found which takes a right-hand operand of type 'const char [2]' (or there is no acceptable conversion)
For situations like this, I've often found it handy to define an overload of operator>> to read a predefined string from a stream:
std::istream &operator>>(std::istream &is, char const *pat) {
char ch;
while (isspace(static_cast<unsigned char>(is.peek())))
is.get(ch);
while (*pat && is && *pat == is.peek() && is.get(ch)) {
++pat;
}
// if we didn't reach the end of the pattern, matching failed (mismatch, premature EOF, etc.)
if (*pat) {
is.setstate(std::ios::failbit);
}
return is;
}
With this, reading your format might look something like this:
istream & operator>>(istream & lhs, MyPoint & rhs) {
return lhs >> "(" >> rhs.x >> "," >> rhs.y >> ")";
}
This will do like most typical overloads and set the stream's fail bit if the pattern you've given isn't matched. As it stands now, each string in the input can be preceded by arbitrary white space (just like conversions for numbers and such).
There is technically a minor bug here: as it stands right now, this uses the global locale's definition of whitespace. To be really correct, it should probably use the definition provided in the locale associated with the input stream.
Also note that I had to change your definition of operator>> bit; in the question it looks like an overload of operator<<, with just those two characters changed to get operator>> instead.
For a quick example:
#include <iostream>
std::istream &operator>>(std::istream &is, char const *pat) {
// implementation above
}
class Point {
int x, y;
friend std::istream &operator>>(std::istream &is, Point &p) {
return is >> "(" >> p.x >>"," >> p.y >> ")";
}
friend std::ostream &operator<<(std::ostream &os, Point const &p) {
return os << "(" << p.x <<", " << p.y << ")";
}
};
int main() {
Point p;
std::cout << "Please enter a point: ";
std::cin >> p;
std::cout << "Thanks. Point: " << p << '\n';
}
Tested with VC++ 2013, VC++ 2015, and g++ 6.1 (but this isn't pushing the limits of compilers at all, so I'd expect it to work fine even with compilers so old they're horribly broken in general (e.g., gcc 2.x or VC++ 6.0).
How could I use operator overloading to add two objects without making it a member of of any object? Is this something to do with insertion operator overloading?
so instead of this, to use something more generic i.e. to be used with any objects?:
sameObjectType operator + ( const sameObjectType &x, const sameObjectType &y ) {
sameObjectType z;
z = x+y;
return z;
}
// I want to do the same for subtraction operatoR
sameObjectType operator - ( const sameObjectType &x, const sameObjectType &y ) {
sameObjectType z;
z = x-y;
return z;
}
You can get the idea from this sample code.
#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'm having a problem with a template ARRAY class. I have another Rational class that i added to this ARRAY class.
what i need it to do is take in rational numbers as fractions (exp 1/2) and sort them. i believe i need to overload the relational operators but thats where im stuck. do i over load them in the ARRAY class or the Rational Class.
below is my code
//generic.cpp
using namespace std;
template<class T>
void Quicksort (T& a, int first, int last);
template<class T>
int split (T& a, int first, int last);
template<class T>
void change (T& e1, T& e2);
template<class T>
void Mergesort(T& a, int first, int last);
template<class T>
void Merge(T& a, int first, int last);
int main()
{
int num;
Rational r1;
cout << "\nHow many rationals? ";
cin >> num;
Array<Rational> r2(num);
cout << "Enter the " << num << " rationals below:\n";
for (int i=0; i<num ; i++)
cin >> r2[i];
cout << "\nThank you!!\n";
cout << "Initially, the rationals are\n"
<< " r2 = " << r2 << "\n";
// Copy the original array and sort it using Quicksort
Array<Rational> r3(r2);
Quicksort(r3, 0, num-1);
cout << "\nElements sorted using quicksort:\n";
for (int i=0; i<num ; i++)
cout << r3[i]<< " ";
cout << "\n";
// Print original list of elements.
cout << "\nOriginal elements:\n";
for (int i=0; i<num ; i++)
cout << r2[i]<< " ";
cout << "\n";
// Copy original array and sort it using MergeSort
Array<Rational> r4(r2);
Mergesort(cm, 0, num-1);
cout << "\nElements sorted using mergesort:\n";
for (int i=0; i<num ; i++)
cout << r4[i]<< " ";
cout << "\n";
return 0;
}
template<class T>
int split (T& a, int first, int last)
{
T::value_type pivot = a[first];
int left = first;
int right = last;
while (left<right)
{
while (pivot < a[right]) //search from right for <=pivot
right--;
while (left<right &&(a[left]<pivot || a[left]==pivot))
left++;
if (left<right)
change(a[left],a[right]);
}
int pivotPosition = right;
a[first] = a[pivotPosition];
a[pivotPosition] = pivot;
return pivotPosition;
}
template<class T>
void Quicksort (T& a, int first, int last)
{
int pos;
if (first < last)
{
pos=split(a,first,last);
Quicksort(a,first,pos); //sort lsft sublist
Quicksort(a,pos+1,last); //sort right sublist
}
}
template<class T>
void change (T& e1, T& e2)
{
T tmp = e1;
e1 = e2;
e2 = tmp;
}
template<class T>
void Mergesort(T& a, int first, int last)
{
if (first < last)
{
int mid = (first + last) / 2;
Mergesort(a, first, mid);
Mergesort(a, mid+1, last);
Merge(a, first, last);
}
}
template<class T>
void Merge(T& a, int first, int last)
{
int mid = (first + last) / 2;
int one = 0, two = first, three = mid + 1;
Array<T::value_type> temp(a.get_size());
while (two <= mid && three <= last) // Neither sublist is done
if (a[two] < a[three]) // Value in first half is smaller
temp[one++] = a[two++];
else // Value in second half is smaller
temp[one++] = a[three++];
while (two <= mid) // Finish copying first half
temp[one++] = a[two++];
while (three <= last) // Finish copying second half
temp[one++] = a[three++];
for (one = 0, two = first; two <= last; a[two++] = temp[one++]);
}
.
//ARRAY.h
using namespace std;
template<class T> class Array
{
public:
typedef T value_type;
Array(int s);
Array(int l, int h);
Array(const Array& other);
~Array();
T& operator[](int index);
const T& operator[](int index) const;
int get_size() const {return arraySize;}
private:
int low;
int high;
int arraySize; //size of array
int offset; //to adjust back to an index of zero
T *array_;
void Copy(const Array&);
};
.
//rational.cpp
using namespace std;
Rational::Rational()
{
num = 0;
den = 1;
}
Rational::Rational(int n, int d)
{
if (d==0){
cout << "Error: division by zero." << endl;
exit(1);
}
num = n;
den = d;
simplify();
}
Rational& Rational::operator+=(const Rational& r)
{
num = (num * r.den) + (den * r.num);
den = den * r.den;
simplify();
return *this;
}
Rational& Rational::operator-=(const Rational& r)
{
num = (num * r.den) - (den * r.num);
den = den * r.den;
simplify();
return *this;
}
Rational& Rational::operator*=(const Rational& r)
{
num *= r.num;
den *= r.den;
simplify();
return *this;
}
Rational& Rational::operator/=(const Rational& r)
{
if (r.num == 0) {
cout << "Error: division by zero." << endl;
exit(1);
}
num *= r.den;
den *= r.num;
simplify();
return *this;
}
const Rational& Rational::operator= (const Rational& rightObj)
{
if (this != &rightObj)
{
num = rightObj.num;
den = rightObj.den;
}
return *this;
}
const Rational Rational::operator-() const
{
Rational answer(-num, den);
return answer;
}
const Rational operator+(const Rational& q, const Rational& r)
{
Rational answer = q ;
answer += r ;
return answer;
}
const Rational operator-(const Rational& q, const Rational& r)
{
Rational answer = q ;
answer -= r ;
return answer;
}
const Rational operator*(const Rational& q, const Rational& r)
{
Rational answer = q ;
answer *= r ;
return answer;
}
const Rational operator/(const Rational& q, const Rational& r)
{
Rational answer = q ;
answer /= r ;
return answer;
}
istream& operator>>(istream& in, Rational& r)
{
char ch;
in >> r.num >> ch >> r.den;
r.simplify();
return in;
}
ostream& operator<<(ostream& out, const Rational& r)
{
if (r.den == 1)
{
out << r.num;
}else
{
out << r.num << "/" << r.den;
}
return out;
}
.
//rational.h
using namespace std;
class Rational
{
friend ostream& operator<< (ostream&, const Rational&);
friend istream& operator>> (istream&, Rational&);
public:
Rational();
Rational(int, int);
double value() const;
Rational reciprocal() const;
Rational& operator+=(const Rational&);
Rational& operator-=(const Rational&);
Rational& operator*=(const Rational&);
Rational& operator/=(const Rational&);
const Rational& operator= (const Rational&);
const Rational operator-() const;
private:
int num;
int den;
void simplify();
};
const Rational operator+(const Rational&, const Rational&);
const Rational operator-(const Rational&, const Rational&);
const Rational operator*(const Rational&, const Rational&);
const Rational operator/(const Rational&, const Rational&);
If you are trying to compare two or more objects of class rational then the relational operators should be methods or friends of class rational. If you need to compare two or more objects of class array then the relational operators should be methods or friends of class array.
You overload them in the Rational class, if you're sorting using the < operator:
bool operator < (const Rational& rhs) const { // rhs = right hand side
// return true if 'this' less than 'rhs'
}
or
bool operator < (const Rational&lhs, const Rational& rhs) {
// return true if 'lhs' less than 'rhs'
}
if you choose to not use a member function
/A.B.