So I am making a program that has two classes monomial and polynomial. Basically a Polynomial is just an array of monomials. I need to create an operator + to add two monomials and return a polynomial. So far I have declared Polynomial as a friend class in monomial and friend Polynomial operator+(const Monomial& a, const Monomial& b); in class Polynomial but it doesnt seem to work.
friend Polynomial operator+(const Polynomial& a, const Monomial& b);
and
friend Polynomial operator+(const Monomial& a, const Polynomial& b);
both work fine so im very confused were the issue lies.
Here is a quick example program that compiles cleanly, of course the contents of Monomial and Polynomial can be changed to your liking.
#include <vector>
class Monomial
{
public:
Monomial() : A(0), x(0) {}
int A;
int x;
};
class Polynomial
{
public:
Polynomial() {}
Polynomial(const Monomial& a, const Monomial& b) {
monomials.push_back(a);
monomials.push_back(b);
}
std::vector<Monomial> monomials;
};
Polynomial operator+(const Monomial& a, const Monomial& b)
{
return Polynomial(a, b);
}
int main(int argc, char *argv[])
{
Monomial a;
Monomial b;
Polynomial poly = a + b;
return 0;
}
Related
This is a grossly simplified version of what I am doing but gets the point across. I have 2 classes that can be used for arithmetic. My problem is I want to be able to multiply the 2 together but anyway I try this seems to cause a problem. For example:
class A {
uint32_t val_;
A(uint32_t src) {
val_=src;
}
friend A operator* (const A &a,const B &b); // <------ throws Unknown type B
};
class B {
uint32_t val_;
bool invert_;
B(A src,bool invert) {
val_=src.val_;
invert_=invert;
}
friend A operator* (const A &a,const B &b);
};
A operator* (const A &a,const B &b) {
if (b.invert_) return a.val_/b.val_;
return a.val_*b.val_;
}
how can I get around this seeming recursive error? If it wasn't for the B value always comes second I would put A operator* (const A &a); in the B class so I can just use friend class B in the A class
So the problem is I didn't know the term forward declaration.
class B; //forward declare B
class A {
uint32_t val_;
A(uint32_t src) {
val_=src;
}
friend A operator* (const A &a,const B &b);
};
class B {
uint32_t val_;
bool invert_;
B(A src,bool invert) {
val_=src.val_;
invert_=invert;
}
friend A operator* (const A &a,const B &b);
};
A operator* (const A &a,const B &b) {
if (b.invert_) return a.val_/b.val_;
return a.val_*b.val_;
}
simple fix when you know the term.
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' ve been trying to make a small library for working with big integers, just as practice, but I get this error for no apparent reason:
Use of overloaded operator '+' is ambiguous (with operand types 'BigNum::BigInt' and 'int')
This is the class definition:
namespace BigNum {
class BigInt {
public:
BigInt();
BigInt(int64_t n);
BigInt(std::string s);
friend std::istream& operator>> (std::istream& in, BigInt& n);
friend std::ostream& operator<< (std::ostream& out, BigInt n);
friend bool operator< (const BigInt& a, const BigInt& b);
friend bool operator> (const BigInt& a, const BigInt& b);
friend bool operator== (const BigInt& a, const BigInt& b);
friend bool operator!= (const BigInt& a, const BigInt& b);
friend bool operator<= (const BigInt& a, const BigInt& b);
friend bool operator>= (const BigInt& a, const BigInt& b);
operator bool();
explicit operator int();
friend void swap (BigInt& a, BigInt& b);
friend BigInt operator+ (BigInt a, BigInt b);
private:
std::vector<int> digits;
std::size_t number_of_digits;
};
}
And these are the methods used:
BigNum::BigInt::BigInt(int64_t n) {
if (n == 0) {
BigInt();
return;
}
// The number is stored in reverse
for (; n; n /= 10)
digits.emplace_back(n % 10);
number_of_digits = digits.size();
}
std::ostream& BigNum::operator<< (std::ostream& out, BigNum::BigInt n) {
for (auto it = n.digits.rbegin(); it != n.digits.rend(); ++it)
out << *it;
return out;
}
void BigNum::swap (BigNum::BigInt& a, BigNum::BigInt& b) {
BigNum::BigInt temp(a);
a = b;
b = temp;
}
BigNum::BigInt BigNum::operator+ (BigNum::BigInt a, BigNum::BigInt b) {
if (a < b)
BigNum::swap(a, b);
BigNum::BigInt result(a);
int transport = 0;
for (std::size_t i = 0; i < b.number_of_digits; ++i) {
result.digits[i] += b.digits[i] + transport;
transport = result.digits[i] / 10;
result.digits[i] %= 10;
}
if (transport)
result.digits.emplace_back(transport);
++result.number_of_digits;
return result;
}
If I write something like:
BigNum::BigInt a = 2;
BigNum::BigInt b = a + 1;
I get that error. I've made the int typecast explicit, but it didn't help out. I don't want to also make the constructor explicit, as that will mean that I'll no longer be able to assign an int to a BigInt (like I did in the previous example).
How can I fix this?
It's not enough to have one explicit conversion operator, you need to make sure that every conversion to a built-in type is explicit. In particular, you should try
explicit operator bool();
to prevent a + 1 from matching the conversion-then-promotion sequence (int)(bool)a and calling operator+(int, int).
I have seen many example to add objects of same class.I was trying to add two different class objects using operator overloading.
Code:
#include<iostream>
using namespace std;
class B;
class A
{
public:
int x;
A(int t=99)
{
x=t;
}
friend const A operator+( A& m, B& n);
friend ostream& operator<<(ostream& os, const A& c);
};
const A operator+(A& c1,B& c2)
{
A temp;
temp.x = c1.x + c2.y;
return temp;
}
ostream& operator<<(ostream &os, const A& c)
{
os << c.x;
return os;
}
class B
{
public:
int y;
B(int e=90)
{
y=e;
}
friend const A operator+( A& m, B& n);
};
int main()
{
A a,u;
B b;
u=a+b;
cout<<"Value of A+B"<<u;
return 0;
}
When i compiled my code it shows Error:
$ g++ operator_overloading.cpp
operator_overloading.cpp: In function ‘const A operator+(A&, B&)’:
operator_overloading.cpp:19:21: error: invalid use of incomplete type ‘struct B’
operator_overloading.cpp:3:7: error: forward declaration of ‘struct B’
What i have done wrong??
The error is clear. You have attempted to use members of B using only a forward declaration.
You have to define the operator after the definition of class B.
For example
#include<iostream>
using namespace std;
class B;
class A
{
public:
int x;
A(int t=99)
{
x=t;
}
friend const A operator+( const A& m, const B& n);
friend ostream& operator<<(ostream& os, const A& c);
};
ostream& operator<<(ostream &os, const A& c)
{
os << c.x;
return os;
}
class B
{
public:
int y;
B(int e=90)
{
y=e;
}
friend const A operator+( const A& m, const B& n);
};
const A operator+(const A& c1, const B& c2)
{
A temp;
temp.x = c1.x + c2.y;
return temp;
}
//...
Otherwise the compiler does not know what data members class B has.
Also it is better to define paraneters of the operator as constant references. In this case the operator can deal with temporary objects.
The error message is caused by the fact that you've defined your const A operator+(A& c1,B& c2) before defining the class B.
At this moment B is hence still an incomplete type (meaning you can only use pointers and references to it, but nothing else).
Just move this definition after you've defined B.
The line class B; forward-declares B. This tells the compiler that a class called "B" exists, but nothing else. When you attempt to use c2.y, where c2 is a B, the compiler does not yet know that B even has a y member.
One solution in this case is to move the definition of B so that it appears before the operator+ definition:
class B;
class A
{
public:
int x;
A(int t=99)
{
x=t;
}
friend const A operator+( A& m, B& n);
friend ostream& operator<<(ostream& os, const A& c);
};
class B
{
public:
int y;
B(int e=90)
{
y=e;
}
friend const A operator+( A& m, B& n);
};
const A operator+(A& c1,B& c2)
{
A temp;
temp.x = c1.x + c2.y;
return temp;
}
Following is a fancy code:
class B
{
private:
int sum;
public:
B ()
{
sum = 0;
}
B& add (int number)
{
sum =+ number;
return *this;
}
};
int main ()
{
B obj;
obj.add (1).add (2).add (3). add (4);
}
Fine, what are the "serious" uses of returning the this pointer from a function call?
An example would be;
class basic_ostream
: ...
{
basic_ostream& operator<<(bool n);
You really want to return this to be able to chain to;
std::cout << boolValue << std::endl;
mycode $ fgrep -r 'return *this' /usr/include/c++/4.4.3 | wc -l
592
mycode $
One use of this is for the Named Parameter Idiom. It depends on method chaining.
class Person;
class PersonOptions
{
friend class Person;
string name_;
int age_;
char gender_;
public:
PersonOptions()
: age_(0), gender_('U')
{}
PersonOptions& name(const string& n) { name_ = n; return *this; }
PersonOptions& age(int a) { age_ = a; return *this; }
PersonOptions& gender(char g) { gender_ = g; return *this; }
};
class Person
{
string name_;
int age_;
char gender_;
public:
Person(const PersonOptions& opts)
: name_(opts.name_), age_(opts.age_), gender_(opts.gender_)
{}
};
Person p = PersonOptions().name("George").age(57).gender('M');
Person p = PersonOptions().age(25).name("Anna");
The initial reason wass for chaining mathematical operations, like this:
class mynumberclass {
int internal;
public:
mynumberclass(int);
mynumberclass operator+(const mynumberclass&) const;
mynumberclass operator-(const mynumberclass&) const;
mynumberclass operator*(const mynumberclass&) const;
mynumberclass operator/(const mynumberclass&) const;
mynumberclass operator%(const mynumberclass&) const;
mynumberclass& operator+=(const mynumberclass&);
mynumberclass& operator-=(const mynumberclass&);
mynumberclass& operator*=(const mynumberclass&);
mynumberclass& operator/=(const mynumberclass&);
mynumberclass& operator%=(const mynumberclass&);
};
int main() {
mynumberclass a(3);
mynumberclass b(4);
mynumberclass c = (a * b + b) / 2; //this chains 3 of the above operators
}
without chaining, that code would have to look like this:
int main() {
mynumberclass a(3);
mynumberclass b(4);
mynumberclass c(a);
c *= b;
c += b;
c /= 2;
}
FredLarson also mentions the Named Parameter Idiom, which is certainly an awesome thing you can use chaining for.
The first thing that comes to mind is chaining functions to perform operations on the same object. jQuery, although not C++, has shown that this can be a very useful paradigm.