If I have the following files, I get this error (c2593 in VC9).
If I un-comment the prototype in main.cpp, the error disappears. I need to maintain the same functionality while keeping the class out of main.cpp. How can I do that?
Thanks.
main.cpp:
#include "number.h"
//const Number operator + (const Number & lhs, const Number & rhs);
int main(void)
{
Number n1(2); // n1 = 2
Number n2(9,3); // n2 = 3
Number n3 = n1+n2; // n3 = 5
}
number.h:
struct Number
{
int num;
Number(int n=0,int d=1) {num = n/d;}
operator int() {return num;}
operator double() {return num*1.0;}
};
number.cpp:
#include "Number.h"
const Number operator + (const Number & lhs, const Number & rhs)
{
Number tmp;
tmp.num = lhs.num + rhs.num;
return tmp;
}
Try putting the prototype in the Number header file:
number.h:
struct Number
{
int num;
Number(int n=0,int d=1) {num = n/d;}
operator int() {return num;}
operator double() {return num*1.0;}
};
const Number operator + (const Number & lhs, const Number & rhs);
number.cpp:
#include "Number.h"
const Number operator + (const Number & lhs, const Number & rhs)
{
Number tmp;
tmp.num = lhs.num + rhs.num;
return tmp;
}
main.cpp:
#include "number.h"
int main(void)
{
Number n1(2); // n1 = 2
Number n2(9,3); // n2 = 3
Number n3 = n1+n2; // n3 = 5
}
You never declare operator + in number.h, you only define it in number.cpp - therefore, when you include number.h in main.cpp, it doesn't know where to go to find operator +.
You must put the declaration of operator + in number.h, outside of the class, then define it in number.cpp
That commented line should go in number.h
EDIT: in number.h but as a free function.
One other thing to note with your code before you go back to us with a very similar question: Better remove the operator int and operator double functions. They will cause you major headache. Let's make a few examples:
Number a, b;
1 + b;
// ambiguous: operator+(int, int) or
// operator+(Number, Number) ?
// did you intend to use those for this case?
float x = a;
// ambiguous: from int -> float or
// double -> float ?
In the original situation you had, your addition was ambiguous, because there were operator+(double, double) and operator+(int, int) builtin operators considered and they were equally well. Others solved that problem. But before you start and run into these other problems, better remove the conversion functions and insert explicit functions like asDouble or something similar.
Apart from other's answers to declare operator+ in the header file, I suggest you to have operator+= in your struct as well.
struct Number
{
// your other declarations.
Number& operator+=(const Number& other)
{
this->num += other.num;
return *this;
}
};
const Number operator+(const Number& lhs, const Number& rhs)
{
Number ret(lhs);
ret += rhs;
return ret;
}
This way it is efficient to call x += y; instead of x = x + y;
Personally I like it better to declare the operators inside the class:
struct Number
{
int num;
Number(int n=0,int d=1) {num = n/d;}
operator int() {return num;}
operator double() {return num*1.0;}
Number operator+(const Number &arg) const;
};
and then:
Number Number::operator+(const Number &arg)
{
...
}
Related
I'm trying to write a class handling multiplication, division, etc of polynomials.
In my header file, I have my class definition, in which I have those public functions :
void Poly_Mult(const Polynomial& Poly);
void Poly_Divide(const Polynomial& Poly);
and also two friend functions :
friend Polynomial Poly_Mult(const Polynomial& Poly1, const Polynomial& Poly2);
friend Polynomial Poly_Divide(const Polynomial& Poly1, const Polynomial& Poly2);
I have defined both Poly_Mult functions with no problem and I try to use them to define the Poly_Divide ones.
For the friend function, I have no problem. However, in the member function :
bool Polynomial::Poly_Divide(const Polynomial& Poly)
{
if (Poly.m_Degree == 0)
return false;
Polynomial result;
result.m_Degree = this->m_Degree - Poly.m_Degree;
result.m_Variable = this->m_Variable;
Polynomial reduced(*this);
double GuidingFactor = Poly.m_Terms[Poly.size() - 1].Factor();
while (reduced.m_Degree >= Poly.m_Degree)
{
int exp = reduced.m_Degree - Poly.m_Degree;
double termFactor = reduced.m_Terms[reduced.size() - 1].Factor() / GuidingFactor;
//I get an error on this next line. The compiler doesn't seem to find to right overloaded function for Poly_Mult
reduced.Poly_Subtract(Poly_Mult(Poly, Polynomial(termFactor, Poly.m_Variable, exp)));
result.m_Terms.push_back(VarPower(termFactor, exp));
reduced.Simplify();
}
result.Simplify();
*this = result;
if(reduced.size() == 1 && reduced.m_Terms[0].Factor() == 0 && reduced.m_Terms[0].Exponent() == 0)
return true;
else
return false;
}
The code is functionally the same in the friend function and it works perfectly as intended, no errors.
instead of the whole detailed function since the friend function works fine, but again, the compiler doesn't seem to find to right overloaded function.
I really don't see the problem here, as the functions have different parameters so I see no ambiguity.
By simplifying the code, I get the same problem with this :
in my header file, I have my class definition :
class Polynomial
{
private:
int m_Degree;
public:
Polynomial(int degree)
: m_Degree(degree) {};
Polynomial(const Polynomial& Poly)
: m_Degree(Poly.m_Degree) {};
Polynomial& operator=(const Polynomial& Poly)
{
m_Degree = Poly.m_Degree;
}
void Multiply(const int& number);
friend Polynomial Multiply(const Polynomial& Object, const int& number);
void Divide(const int& number);
friend Polynomial Divide(const Polynomial& Object, const int& number);
};
Then, in my cpp file, I have the implementation of the functions :
#include "Polynomial.h"
void Polynomial::Multiply(const int& number)
{
m_Degree *= number;
}
Polynomial Multiply(const Polynomial& Object, const int& number)
{
return Polynomial(Object.m_Degree * number);
}
void Polynomial::Divide(const int& number)
{
Polynomial copy = *this;
Polynomial result = Multiply(copy, (1./number)); //This is where the problem is. The compiler doesn't find the right overloaded function
*this = result;
}
Polynomial Divide(const Polynomial& Object, const int& number)
{
Polynomial result = Multiply(Object, (1. / number));
return result;
}
I get those errors :
error C2660: 'Polynomial::Multiply': function does not take 2 arguments
no suitable constructor exists to convert from "void" to "Polynomial"
I have two classes Integer and Fraction and one abstract class Number. I am suppose to perform addtion operation by overloading + and also I need to check equality of values using overloading of == operator on these classes.
Operations to be performed
1. Add Integer + Integer = Integer
2. Add Fraction + Fraction = Fraction
3. Add Integer + Fraction = Fraction
I have been able to do 1st and 2nd operation but not able to do addition of integer and fraction.
Below is the code snippet:
Number.h
#pragma once
#include <iostream>
template<class T>
class Number
{
virtual const T operator+ (const T &) = 0;
virtual void display(std::ostream &) const = 0;
virtual bool operator==(const T& rhs) const = 0;
};
Integer.h
#pragma once
#include "Number.h"
#include "Fraction.h"
class Integer : public Number<Integer>
{
int intValue;
public:
void display(std::ostream &) const;
int getValue() const;
void setValue(int);
Integer() {}
Integer(int num);
const Integer operator+ (const Integer &);
virtual ~Integer() {}
bool operator==(const Integer&) const;
};
Integer.cpp
#include "Integer.h"
#include "Number.h"
#include <iostream>
#include <string>
// parameterized constructor
Integer::Integer(int num)
{
intValue = num;
}
// return integer value
int Integer::getValue() const
{
return this->intValue;
}
void Integer::setValue(int x)
{
this->intValue = x;
}
// operator "+" overloading
const Integer Integer::operator+(const Integer &secondNumber)
{
Integer temp = this->intValue + secondNumber.intValue;
return temp;
}
// operator "=" overloading
void Integer::display(std::ostream& stream) const
{
stream << this->intValue;
}
// comparasion operator overload
bool Integer::operator==(const Integer& rhs) const
{
return this->intValue == rhs.intValue;
}
Fraction.h
#pragma once
#include "Number.h"
#include "Integer.h"
class Fraction : public Number<Fraction>
{
Integer _numerator;
Integer _denominator;
public:
void display(std::ostream &) const;
Fraction() = delete;
Fraction(const int &, const int &);
const Fraction operator+ (const Fraction &);
int gcdCalculate(int val1, int val2);
int lcmCalculate(const int val1, const int val2);
virtual ~Fraction() {}
bool operator==(const Fraction& rhs) const;
};
Fraction.cpp
#include "Fraction.h"
#include <iostream>
// parameterised constructor
Fraction::Fraction(const int & num, const int & den)
{
_numerator.setValue(num);
_denominator.setValue(den);
}
// display the fraction value
void Fraction::display(std::ostream & stream) const
{
if (this->_denominator == 0)
std::cout << "Undefined: " << this->_numerator.getValue() << "/" << this->_denominator.getValue() << " (Divide By Zero Exception)";
else
stream << this->_numerator.getValue() << "/" << this->_denominator.getValue();
}
// "+" operator overloading
const Fraction Fraction::operator+(const Fraction &numberTwo)
{
int lcm = lcmCalculate(this->_denominator.getValue(), numberTwo._denominator.getValue());
int multiplier1 = 0;
if (this->_denominator.getValue())
multiplier1 = lcm / this->_denominator.getValue();
int multiplier2 = 0;
if (numberTwo._denominator.getValue())
multiplier2 = lcm / numberTwo._denominator.getValue();
return Fraction((this->_numerator.getValue() * multiplier1) + (numberTwo._numerator.getValue() * multiplier2), lcm);
}
// LCM Calculation
int Fraction::lcmCalculate(const int val1, const int val2)
{
int temp = gcdCalculate(val1, val2);
return temp ? (val1 / temp * val2) : 0;
}
// GCD Calculation
int Fraction::gcdCalculate(int val1, int val2)
{
for (;;)
{
if (val1 == 0) return val2;
val2 %= val1;
if (val2 == 0) return val1;
val1 %= val2;
}
}
// comparision operator overload
bool Fraction::operator==(const Fraction& rhs) const
{
Integer numCheck = this->_numerator;
Integer denCheck = this->_denominator;
if (rhs._numerator.getValue())
numCheck.setValue(numCheck.getValue() / rhs._numerator.getValue());
if (rhs._numerator.getValue())
denCheck.setValue(denCheck.getValue() / rhs._denominator.getValue());
if (numCheck == denCheck) {
return true;
}
return false;
}
QUESTION:
I am confused as how to add Integer + Fraction class.
Do I need to create another class which will inherit from Number class.
How to overload oprator+ present in Number Class.
Suppose I try to add Integer + Fraction = Fraction in the Integer class itself then I will have something like
Example
class Integer : public Number<Integer>
{
const Fraction operator+(const Fraction &);
}
const Fraction Integer::operator+(const Fraction &numberTwo)
{
^^ I will get error here
// Addition opeartion
}
Please help me.
For your first question, the solution is to not use member function overloads, but to create a non-member function overload, e.g.
Fraction operator+(Integer const& integer, Fraction const& fraction)
{
// Logic to add the integer and fraction here
// Perhaps something like...
Fraction f(integer.getValue(), 1); // Create fraction
return f + fraction;
}
The code above uses the Fraction::operator+ function to add the integer.
While you can add an Integer+Fraction operator to your current design like Joachim suggested, that's going to result in some code duplication or at least some unnecessary boilerplate.
I suggest an alternative design instead: Make Integer convertible to Fraction. After all, any integer can be represented by the Fraction type, right?
You can make Integer convertible in two ways: By adding a conversion function to Integer, or by adding a converting constructor to Fraction.
I recommend choosing the converting constructor approach, because Fraction already depends on Integer type and so the cast operator would result in a circular dependency, just like your member operator attempt. I'll leave the implementation as an exercise.
This design requires that the addition operator is implemented as a non-member overload:
Fraction operator+(Fraction const& left, Fraction const& right)
With the converting constructor, this function can handle any combination of (F + F), (F + I) and (I + F).
I had a question on operator overloading. Below is my the example code. If you can read through it and my question is below.
//class definition
class example
{
private:
int a ; // Defined in FeetInches.cpp
public:
void seta(int f)
{
a = f;
}
example operator + (const example &); // Overloaded +
int geta()
{
return a;
}
};
example example::operator + (const example &right)
{
example temp;
temp.a = a + right.a;
return temp;
}
//main
#include "header" //this is the class definition above
#include <iostream>
using namespace std;
int main()
{
example r;
r.seta(1);
example s;
s.seta(1);
example t;
t = r + s;
t = r + 1; //if included it won't compile
t = 1 + r; //if included it won't compile
int x = t.geta();
cout << x;
cin.get();
return 0;
}
I understand that when you attempt to add to objects together using operator overloading they should be the same.
Here is the question:
I recently saw when the object was on one side of the operator it compiled but when it was on the other it didn't. Such as:
t = r + 1; it compiled.
t = 1 + r; it didn't.
(Also I know in my example it doesn't work either way but was just easier to frame question with code.)
How does operator overloading compile when the object is on one side of the operator but not compile when it is on the other.
Thanks
If you rewrite the offending statement verbosely, it looks like:
t.operator=(1.operator+(r));
Which doesn't make a lot of sense and confuses the compiler.
Being confused, it can either convert the number 1 to an instance of example or convert the variable r to an integer. Unfortunately, you don't supply enough information in your class to do either.
If you provide a constructor for your class that takes an integer, things may come out less confusing:
class example
{
public:
example(int new_value) : a(new_value)
{ ; }
};
Now you have provided the compiler with a method convert integers into examples.
Another alternative is to provide a casting or conversion operator:
class example
{
public:
int operator int (const example& e)
{
return e.a;
}
};
There are other alternatives, such as creating an addition method that takes an integer.
Edit 1:
If you are designing a units class beware of constants. You have no idea what unit the constant is in, such as feet or inches. The compiler won't be able to help, since numerical constants don't have units associated with them.
It's really simple, when you overloading operator you can do it in two ways:
First is like you do it. You inserted overloaded operator for your class in it. This way the left argument must be the object of this class. Why? Because when you call this operator you can do it as call of every function in your class. You can't do it other way, because you can't call this function by other type.
Second, you made overloaded operator as friend to your class.
In your class you put this line:
friend example& operator + (const example &left, const example &right);
And after your class definition you put this:
example& operator + (const example &left, const example &right){...}
So if you want to add integer or other types you must just modify your operator to add it like this:
example& operator + (const example &left, const int right){...}
or this:
example& operator + (const int left, const example &right){...}
Choose one or both if you want to add int from left or rigth side of the opearator.
t = r + 1; means t = r.operator+(1); if r defines a matching operator+() method, otherwise it means t = operator+(r, 1); instead. It does not compile because you did not define any + operator that takes an example on the left and an int on the right, eg:
// as a class method:
class example
{
...
public:
...
example operator + (int right) const;
};
example example::operator + (int right) const
{
example temp;
temp.seta(a + right);
return temp;
}
Or:
// as a global operator:
class example
{
...
public:
...
friend example operator + (const example& left, int right);
};
example operator + (const example& left, int right)
{
example temp;
temp.seta(left.a + right);
return temp;
}
If you had defined a contructor that takes an int as input, the compiler could have created a temp example when you pass an int value to the example::operator+(const example&) method, eg:
class example
{
...
public:
example (int f);
...
example operator + (const example& right);
};
example::example::(int f)
: a(f)
{
}
example example::operator + (const example& right)
{
example temp;
temp.a = a + right.a;
return temp;
}
Likewise, t = 1 + r; means t = operator+(1, r); (since 1 is not a class type). It does not compile because you did not define a global + operator that takes an int on the left and an example on the right:
class example
{
...
public:
...
friend example operator + (int left, const example& right);
};
example operator + (int left, const example& right)
{
example temp;
temp.a = left + right.a;
return temp;
}
I have such code
class Number
{
int m_value;
public :
Number(const int value) :
m_value(value)
{
}
operator const int() const
{
return m_value;
}
int GetValue() const
{
return m_value;
}
};
bool operator==(const Number& left, const Number& right)
{
return left.GetValue() == right.GetValue();
}
class Integer
{
int m_value;
public :
Integer(const int value) :
m_value(value)
{
}
operator const int() const
{
return m_value;
}
bool operator==(const Integer& right) const
{
return m_value == right.m_value;
}
bool operator==(const int right) const
{
return m_value == right;
}
int GetValue() const
{
return m_value;
}
};
bool operator==(const int left, const Integer& right)
{
return left == right.GetValue();
}
int main()
{
Number n1 = 1;
Number n2 = 1;
int x3 = 1;
n1 == n2;
n1 == x3; // error C2666: 'operator ==' : 3 overloads have similar conversions
x3 == n1; // error C2666: 'operator ==' : 2 overloads have similar conversions
Integer i4 = 1;
Integer i5 = 1;
i4 == i5;
i4 == x3;
x3 == i4;
return 0;
}
For class Number I have two errors as shown in the code above. For class Integer everything is OK. The problem is, I want to keep in resulting class single-parameter constructor, cast operator and equality operations (MyClass == int, int == MyClass, MyClass == MyClass), but I want to implement only one version of operator== as in class Number. I don't see any way to do this. Is that even possible or I must have all three implementations as in class Integer? I know why I get these errors I just don't like the solution I have.
In class Number you define a conversion operator to int and your constructor allows converting an int to a Number. Therefore, when comparing a Number n and an int x for equality, ambiguity arises: should the compiler invoke the built-in operator == for ints and convert n to an int, or should it rather pick your operator and convert x to a Number? Both conversions are equally good, and it can't choose one.
So yes you have to define three versions, or add a template operator which can perfectly match the type of all arguments and forward to your operator explicitly, like this one (but you most likely want to guard it with some enable_if to limit its applicability only to the appropriate T and U):
template<typename T, typename U> // beware: this will match anything. to be constrained
bool operator == (T n, U const& u)
{
return (Number(n) == Number(u));
}
You can define only one operator== as member function:
bool operator==(const int& right) const
{
std::cout << "custom\n";
return this->GetValue() == right;
}
Then,
n1==n2: n2 will be converted to int and custom operator will be used.
n1 == n3: custom operator will be used
n3==n1: built-in operator will be used
Note, that you want your operator== be const to be able to compare constant Numbers
In C++11 you can make operator int explicit.
Another approach would be to use SFINAE to have a template == that works for one or more Number args, but that is using a bazooka to kill an ant.
Whats wrong with my code shown below? please somebody throw some light. Thanks for your time !
#include<iostream.h>
using namespace std;
struct mydata{
int mx;
mydata(int x = 0){}
mydata operator+(const mydata& rhs){
mydata temp(rhs);
return temp;
}
operator int() const{ return mx; }
operator double() const{ return mx; }
};
int main(){
mydata d;
mydata r = d + 5; // L1
5 + d; // L2
d + d; // L3
}
First, you haven't stated what the problem is, but presumably you want an operator+ that sums the mx values of two mydata objects:
mydata operator+(const mydata& rhs){
return mydata (mx + rhs.mx);
}
Next, I would suggest making this a non-member function, so that the LHS and RHS get treated in the same way, fixing the problem in L2:
mydata operator+(const mydata& lhs, const mydata& rhs){
return mydata (lhs.mx + rhs.mx);
}
Finally, you will have an ambiguous overload remaining, because the compiler cannot decide whether to use the built-in operator+(int,int) or your own operator+(const mydata&, const mydata&). You can fix this by removing the cast operators int() and double().
See demo here.
The problem (stated the comment) is that compiler doesn't know which + you want to execute:
(double)d + 5
or
(int)d + 5
In order to resolve this ambiguoity, you should point the type conversion, or replace one of these operators by a named function:
operator int() const{ return mx; }
operator double() const{ return mx; }
If you want instead use d + mydata(5) you should write so, because the above variants are more likely to be applied
You could provide a few non-member operator+ to enable operator+ with different data type:
mydata operator+(const mydata& lhs, const mydata& rhs){
return mydata (lhs.mx + rhs.mx);
}
mydata operator+(int mx, const mydata& rhs){
return mydata (rhs.mx+mx);
}
mydata operator+(const mydata& lhs, int mx){
return mydata(lhs.mx+mx);
}
You can't do 5 + d. 5 can not be converted to class object like this. For this you need to get the operator + definition out of the class method. (in my knowledge preferably friend).