im new to C++, although i do know the general C syntax. I've been trying to create a class with operator overloading. But i can't get it to work. Well partially got it to work.
Working operator overloading in same source:
//test.cpp
#include <iostream>
class Fraction
{
int gcd(int a, int b) {return b==0 ? a : gcd(b,a%b); }
int n, d;
public:
Fraction(int n, int d = 1) : n(n/gcd(n,d)), d(d/gcd(n,d)) {}
int num() const { return n; }
int den() const { return d; }
Fraction& operator*=(const Fraction& rhs) {
int new_n = n*rhs.n / gcd(n*rhs.n, d*rhs.d);
d = d*rhs.d / gcd(n*rhs.n, d*rhs.d);
n = new_n;
return *this;
}
};
std::ostream& operator<<(std::ostream& out, const Fraction& f){
return out << f.num() << '/' << f.den() ;
}
bool operator==(const Fraction& lhs, const Fraction& rhs) {
return lhs.num() == rhs.num() && lhs.den() == rhs.den();
}
bool operator!=(const Fraction& lhs, const Fraction& rhs) {
return !(lhs == rhs);
}
Fraction operator*(Fraction lhs, const Fraction& rhs)
{
return lhs *= rhs;
}
int main()
{
Fraction f1(3,8), f2(1,2), f3(10,2);
std::cout << f1 << '*' << f2 << '=' << f1*f2 << '\n'
<< f2 << '*' << f3 << '=' << f2*f3 << '\n'
<< 2 << '*' << f1 << '=' << 2 *f1 << '\n';
}
Output:
3/8*1/2=3/16
1/2*5/1=5/2
2*3/8=3/4
Source: http://en.cppreference.com/w/cpp/language/operators
Now my code, trying to apply the code from above
//vectors.h
class Vector2
{
public:
Vector2(void);
~Vector2(void);
int counter;
Vector2& operator+=(const Vector2& vec);
}
//vectors.cpp
#include "vectors.h"
Vector2::Vector2(void)
{
counter = 0;
}
Vector2::~Vector2(void)
{
}
Vector2& operator+=(Vector2& vec)//error: too few parameters
{
int new_n = counter + vec.counter;
counter = new_n;
return *this;//error: this may only be used in a non-static member function.
}
//main.cpp
#include <stdio.h>
#include "vectors.h"
int main(void)
{
Vector2 vector();
while(true)
{
vector += vector;//error: expression must be a modifiable value
printf("Vector counter: %d\n",vector.counter);
}
}
What i'm trying to do:
I'm trying to make my own class, and use operator overloading. But the part i can't get to work is defining the class with a header while keeping operator overloading working.
Thanks for reading my question
The following compiled in ideone: http://ideone.com/ratVVT
Changes are:
Implementation of (overload) method must specify the Class name
Implementation of (overload) method must have the same signature as the declaration (missing const).
Declaring the variable vector in main Vector2 vector(); was interpreted as a function declaration, instead of a Vector2 variable.... use Vector2 vector; or Vector2 vector=Vector2()
The code copied below.
#include <iostream>
//vectors.h
class Vector2
{
public:
Vector2();
~Vector2();
int counter;
Vector2& operator+=(const Vector2& vec);
};
//vectors.cpp
//#include "vectors.h"
Vector2::Vector2()
{
counter = 0;
}
Vector2::~Vector2()
{
}
Vector2& Vector2::operator+=(const Vector2& vec)// <---- CHANGE
{
int new_n = counter + vec.counter;
counter = new_n;
return *this;//error: this may only be used in a non-static member function.
}
//main.cpp
#include <stdio.h>
//#include "vectors.h"
int main()
{
Vector2 vector; // <---- CHANGE
while(true)
{
vector += vector;
printf("Vector counter: %d\n",vector.counter);
}
}
You are missing the class name in your method definition Vector2:: and the signature does not match because of the first parameter missing a const.
Vector2& Vector2::operator+=(const Vector2& vec)
Related
I am trying to create a program that manipulates with arrays of complex numbers, my program has two classes, class that represents complex numbers and class that represents an array.
Here's the code that i created so far:
Complex.h
#pragma once
#include <functional>
class Complex
{
friend class Array;
double re, im;
friend std::ostream& operator<<(std::ostream&, const Array&);
friend std::istream& operator>>(std::istream&, Array&);
public:
double getRe() const;
double getIm() const;
void setRe(double);
void setIm(double);
Complex operator[](int);
Complex operator=(const Complex&);
Complex operator+(const Complex&);
Complex operator-(const Complex&);
private:
Complex apply(const Complex&, const std::function <double(double, double)> &);
};
Array.h
#pragma once
#include "Complex.h"
#include <functional>
class Array
{
Complex *arr;
int n;
friend std::ostream& operator<<(std::ostream&, const Array&);
friend std::istream& operator>>(std::istream&, Array&);
public:
Array();
Array(int);
Array(const Array&);
Array(Array&&);
~Array();
Array& operator=(const Array&);
Array& operator=(Array &&);
Array operator+(const Array&);
// Array operator-(const Array&);
private:
Array& copy(Array&);
Array& move(Array&);
Array compute(const Array &,const std::function<Complex(Complex, Complex)> &f);
};
Complex.cpp
#include <iostream>
#include "Complex.h"
double Complex::getRe() const
{
return re;
}
double Complex::getIm() const
{
return im;
}
void Complex::setRe(double re)
{
this->re = re;
}
void Complex::setIm(double im)
{
this->im = im;
}
Complex Complex::operator[](int i)
{
Complex temp;
temp.re = re;
temp.im = im;
return temp;
}
Complex Complex::operator=(const Complex &c)
{
re = c.re;
im = c.im;
return *this;
}
Complex Complex::operator+(const Complex &c)
{
*this = apply(c, [](double x, double y) { return x + y; });
return *this;
}
Complex Complex::operator-(const Complex &c)
{
*this = apply(c, [](double x, double y) { return x - y; });
return *this;
}
Complex Complex::apply(const Complex &c, const std::function<double(double, double)> &f)
{
re = re + c.re;
im = im + c.im;
return *this;
}
Array.cpp
Array::Array(int n)
{
this->n = n;
arr = new Complex[n];
}
Array::Array(const Array &a)
{
this->n = a.n;
arr = new Complex[n];
arr = a.arr;
}
Array::Array(Array &&a)
{
this->n = a.n;
arr = a.arr;
a.arr = nullptr;
}
Array& Array::operator=(const Array &a)
{
this->n = a.n;
arr = new Complex[n];
arr = a.arr;
return *this;
}
Array& Array::operator=(Array &&a)
{
this->n = n;
this->arr = a.arr;
a.arr = nullptr;
return *this;
}
std::ostream& operator<<(std::ostream& out, const Array &a)
{
for (int i = 0; i < a.n; i++)
out << a.arr[i].re << " +i" << a.arr[i].im;
return out;
}
std::istream& operator>>(std::istream& in, Array &a)
{
for (int i = 0; i < a.n; i++)
in >> a.arr[i].re >> a.arr[i].im;
return in;
}
Array Array::operator+(const Array &a)
{
return compute(a, [](Complex x, Complex y) { return x + y; });
}
/*
Array Array::operator-(const Array &a)
{
return compute(a, [](Complex x, Complex y) { return x - y; });
}
*/
Array Array::compute(const Array &a,const std::function<Complex(Complex , Complex)> &f)
{
for (int i = 0; i < n; i++)
arr[i] = f(arr[i], a.arr[i]);
return *this;
}
Array::~Array()
{
delete[] arr;
n = 0;
}
Source.cpp
#include <iostream>
#include "Array.h"
#include "Complex.h"
int main()
{
Array a(2);
std::cin >> a;
Array b;
b = a;
Array c(2);
c = a + b;
std::cout << c;
getchar();
getchar();
}
So this is what i have at the moment, i need to add that this worked just fine before, when in my Complex class i only had setters, getters, these fields and Array class as a friend, which means that i was doing indexing "manually" and operations + and - without overloading of corresponding operators in Complex class.
However, i had an idea that it would be better (and more in the spirit of oop) to overload the operators that i need for Complex class since code would be more readable.
However, even though i get the result i need, every time after execution of program, when i hit enter, error with destructor appears, i tried some debugging and it appears to me that problem appears when object Array b is "destructed", but i could not figure out what actually happens (and is b actually causing the problem in the first place).
NOTE: I've found some questions here related to complex arrays but non of them solved my problem.
Any help appreciated!
I would like to add an option to make a chained comparison on objects of MyClass. For example:
MyClass one;
MyClass two;
MyClass three;
/*....*/
if (one == two == three){
/*....*/
}
So that if all are equal it will return true, else it will return false.
I currently have this operator overload that works fine when comparing only two instances of MyClass:
bool operator==(const MyClass &other);
I understand that one==two==three is equal to ((one==two)==three) so I guess that should change my operator== to be something like:
MyClass& operator==(const MyClass &other);
But I couldn't manage to understand how to complete this in order to be able to compare more than two instances in a row (chained).
As pointed out in comments, it's not good to break the usual semantics in such a way. The Principle of least Astonishment should be followed as mentioned.
But I couldn't manage to understand how to complete this in order to be able to compare more than two instances in a row (chained).
Not that I think it's really a good idea to do so1, but here's a working solution:
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass(int x_) : x(x_), isfalse(false) {}
const MyClass& operator==(const MyClass& rhs) const {
if(!isfalse && x == rhs.x) {
return rhs;
}
return FalseInst;
}
operator bool() const {
return !isfalse;
}
private:
int x;
MyClass() : x(), isfalse(true) {}
const bool isfalse;
static MyClass FalseInst;
};
MyClass MyClass::FalseInst;
int main()
{
MyClass one(1);
MyClass two(1);
MyClass three(1);
if(one == two == three) {
cout << "Yay!" << endl;
}
MyClass four(1);
MyClass five(0);
MyClass six(0);
if(!(four == (five == six))) {
cout << "Yay!" << endl;
}
}
Live Demo
1) Note the warning issued by the compiler.
As a purely theoretical problem, here is a way to solve it:
#include <iostream>
using namespace std;
class A {
public:
int x;
A(int x = 0) : x(x) {}
struct Cmp {
const A *ptr;
mutable bool val;
operator bool() const {
return val;
}
const Cmp &operator == (const A &other) const {
return other == *this;
}
};
bool isEqualTo (const A &other) const {
return x == other.x;
}
Cmp operator == (const A &other) const {
return {this, isEqualTo(other)};
}
const Cmp &operator == (const Cmp &other) const {
//other.val = other.val && (*this == *other.ptr).val;
other.val &= other.ptr->isEqualTo(*this);
return other;
}
};
int main() {
cout << (A(10) == A(10) == A(10)) << endl;
cout << (A(10) == A(9) == A(10)) << endl;
return 0;
}
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();
}
is it possible to overload the operator% for two doubles?
const double operator%(const double& lhs, const double& rhs)
{
return fmod(lhs, rhs);
}
Of course, this generates an error because one of the two parameters must have a class type.
So I thought about utilizing the possibility of implicit constructor calls of C++ to get around of this problem. I did it in the following way:
class MyDouble {
public:
MyDouble(double val) : val_(val) {}
~MyDouble() {}
double val() const { return val_; }
private:
double val_;
};
const double operator%(const MyDouble& lhs, const double& rhs)
{
return fmod(lhs.val(), rhs);
}
const double operator%(const double& lhs, const MyDouble& rhs)
{
return fmod(lhs, rhs.val());
}
... and:
double a = 15.3;
double b = 6.7;
double res = a % b; // hopefully calling operator%(const MyDouble&, const double) using a implicit constructor call
Unfortunately, this does not work! Any hints, ideas, ... are appreciated!
Thanks in advance,
Jonas
The reason this doesn't work is because overload resolution for user defined operator functions is only triggered if at least one operand of the expression has a class or enumeration type.
So you are out of luck. This won't work.
I think the best you could try is waiting for a C++0x compiler and instead of writing 3.14, you write 3.14_myd, as a user defined literal.
alternatively, implement double MyDouble::operator%(const double&) const;, like so:
#include <iostream>
#include <cmath>
class t_double {
public:
t_double(const double& val) : d_val(val) {
}
t_double(const t_double& other) : d_val(other.d_val) {
}
~t_double() {
}
const double& val() const {
return this->d_val;
}
double operator%(const double& rhs) const {
return fmod(this->val(), rhs);
}
double operator%(const t_double& rhs) const {
return fmod(this->val(), rhs.val());
}
private:
double d_val;
};
int main(int argc, char* const argv[]) {
const t_double a(15.3);
const t_double b(6.7);
std::cout << a % b << " == " << a.val() << " % " << b.val() << "\n";
return 0;
}
What do these errors mean?
Vector.cpp:13: error: ISO C++ forbids declaration of ‘Vector’ with no type
Vector.cpp:13: error: explicit qualification in declaration of ‘void Vector::Vector(double, double, double)’
The C++ (Line 13 is the Vector::Vector( ...):
#include <iostream>
using namespace std;
namespace Vector
{
Vector::Vector( double x, double y, double z)
{
a = x;
b = y;
c = z;
}
/*
double Vector::dot(const Vector &v) const
{
return (a*v.a)+(b*v.b)+(c*v.c);
}
*/
Vector Vector::operator+(const Vector &v) const
{
Vector v1( a + v.a, b + v.b, c + v.c );
return v1;
}
Vector Vector::operator-(const Vector &v) const
{
Vector v1( a - v.a, b - v.b, c - v.c );
return v1;
}
bool Vector::operator==(const Vector &v) const
{
if( (a == v.a) && (b == v.b) && (c == v.c) )
{
return true;
}
else
{
return false;
}
}
Vector Vector::operator*(const Vector &v) const
{
Vector v1( b*v.c - c*v.b, c*v.a - a*v.c, a*v.b - b*v.a );
return v1;
}
ostream& operator<<(ostream &out, const Vector &v)
{
out << "<" << v.a << ", " << v.b << ", " << v.c << ">";
return out;
}
istream& operator>>(istream &in, Vector &v)
{
in >> v.a;
in >> v.b;
in >> v.c;
return in;
}
/*
double length( Vector v )
{
return sqrt( (v.a*v.a)+(v.b*v.b)+(v.c*v.c) );
}
*/
} // end namespace Vector
The header file:
#ifndef _VECTOR_H
#define _VECTOR_H
#include <cstdlib>
#include <iostream>
using namespace std;
namespace Vector
{
class Vector
{
private:
double a;
double b;
double c;
public:
Vector( double x=0.0, double y=0.0, double z=0.0);
double dot(const Vector &v) const;
Vector operator+(const Vector &v) const;
Vector operator-(const Vector &v) const;
bool operator==(const Vector &v) const;
Vector operator*(const Vector &v) const;
friend ostream& operator<<(ostream &out, const Vector &v);
friend istream& operator>>(istream &in, Vector &v);
}; // end Vector class
double length(Vector v);
} //end namespace Vector
#endif /* _VECTOR_H */
Constructors have no return type, not even void. Just remove the void and you're fine.
Looks like the major problem is that your cpp files didn't include your header file.
Include the header file in the cpp file. Also, the code has some design issues. operator+ should return const Vector and the same case with operator-.