Qt overloading operators [duplicate] - c++

This question already has an answer here:
simple c++: How to overload the multiplication operator so that float*myClass and myClass*float works
(1 answer)
Closed 9 years ago.
i'm trying write a polynomial class that can be used for calculation.
class Polynomial
{
public:
Polynomial(QString s); // creates a polynomial with QRegExp
const Polynomial operator+(Polynomial const& rhs); // NOT TESTED
const Polynomial operator+(double d);
const Polynomial operator-(Polynomial const& rhs); //
const Polynomial operator-(double d);
const Polynomial operator-();
private:
void resizeToMin();
QList<int> exp;
QList<double> coeff;
QChar var;
};
i would want to use the Polynomial like this:
Polynomial p("3*x^2 + x^1 -1");
double a = 2.0;
p = p*2 // this works
p = p*a // this works
p = 2*p // DOES NOT WORK
p = a*p // DOES NOT WORK
same for + and -
is this even possible? it would allow me to calculate with polynomials in the same way as with doubles
thanks in advance

Your operators only go one direction as you have them defined. As your class stands, you have the left side always be a Polynomial which won't work for double*Polynomial wherein the double is on the left side.
Since multiplication of polynomials is commutative (I think that's the word...a*b=b*a), you can define an operator like this outside the class:
Polynomial operator+(const double& lhs, const Polynomial& rhs) {
return rhs + lhs; //switch the operation so that the polynomial is on the left hand side
}
It will take in the double as the lefthand side and apply it as if it were the right hand side.
Adapted from this answer: https://stackoverflow.com/a/15741776/1124529
The linked answer also explains a little about doing operations if the operation is not commutative.

Related

c++ simple operator overloading for both directions

So I am trying to overload the operator* so both ways will work:
Myclass * a;
a * Myclass;
When I declare this function everything goes well:
Polynomial operator*(const double d);
But when I try doing it the other direction like this:
Polynomial operator*(Polynomial &, const double d)
I'm getting an error: "too many parameters for this operator function.
What am I doing wrong?
Thanks!
When you overload a binary operator as a member function, the class instance is always the left-hand operator and the argument to the function is the right hand, there's nothing you can do to change it. Not if you want to continue using member only functions.
But if you use a global non-member function you can easily have whichever order you want. For example
class Polynomial { ... };
// Function that allows poly * 12.34
Polynomial operator*(const Polynomial& lhs, const double rhs)
{
...
}
// Function which allows 12.34 * poly
Polynomial operator*(const double lhs, const Polynomial& rhs)
{
...
}
And if you don't want to reimplement the same code in both functions, and the operator is commutative (like multiplication and addition should be) then you can implement one of the function by calling the other:
Polynomial operator*(const Polynomial& lhs, const double rhs)
{
...
}
Polynomial operator*(const double lhs, const Polynomial& rhs)
{
return rhs * lhs; // Calls the operator function above
}
Of course, the operator taking the Polynomial object as left-hand side may of course be implemented as a member function.
On a related note, if you have implemented the operator as a member function, e.g.
class Polynomial
{
...
Polynomial operator*(const double rhs)
{
...
}
};
The the following code
Polynomial poly1(...);
Polynomial poly2 = poly * 12.34;
is equal to
Polynomial poly1(...);
Polynomial poly2 = poly.operator*(12.34);

Inherent Circular Dependency C++ Vertex and Vectors

I have two classes, a vertex and a vector, I am trying to use operators to make life simpler. If you'll examine the vector and vertex classes presented below I'm trying to implement operators in both vertex and vector.
For example
VertexA+VertexB = VectorC //Isn't used that much...
VertexA-VertexB = VectorC //Could be used very frequently
VertexA+VectorB = VertexC //Could be used very frequently
VertexA-VectorB = VertexC //Could be used very frequently
VectorA+VectorB = VectorC //used
VectorA-VectorB = VectorC //used
VectorA+VertexB = VertexC //used
VectorA-VertexB = VertexC //used
If you'll notice there is a circular dependency. In order for the operators of one class to return by value( not by reference or pointer)
I know one work around, express vertexes just as vectors. However I was wondering if there was a different solution because I like the two different classes just for clarity.
#ifndef decimal
#ifdef PRECISION
#define decimal double
#else
#define decimal float
#endif
#endif
class Vector;
class Vertex{
public:
decimal x,y;
const Vertex operator+(const Vector &other);
const Vertex operator-(const Vector &other);
const Vector operator+(const Vertex &other);
const Vector operator-(const Vertex &other);
};
class Vector{
public:
decimal x,y;
const Vector operator+(const Vector &other) const {
Vector result;
result.x=this->x+other.x;
result.y=this->y+other.y;
return result;
}
const Vector operator-(const Vector &other) const {
Vector result;
result.x=this->x-other.x;
result.y=this->y-other.y;
return result;
}
const Vertex operator+(const Vertex &other) const {
Vertex result;
result.x=this->x+other.x;
result.y=this->y+other.y;
return result;
}
const Vertex operator-(const Vertex &other) const {
Vertex result;
result.x=this->x-other.x;
result.y=this->y-other.y;
return result;
}
decimal dot(const Vector &other) const{
return this->x*other.x+this->y*other.y;
}
const decimal cross(const Vector &other) const{
return this->x*other.y-this->y*other.x;
}
};
To make code of this type of things (Arithmetic data types) easy to write, normally I use a set of templates called "Operator overloading helpers", like Boost operators header.
Checkout my implementation.
The advantage of this approach is that the implementation of the operators is coherent (operator+=implementation is coherent with operator+implementation, etc).
In your case, if you only implement Vertex& operator+=(const Vector& other) , Vertex& operator-=(const Vector& other) , Vector& operator+=(const Vector& other) , and Vector& operator-=(const Vector& other); you cover your 3th to 5th cases. How?
Check this code:
//Forward declaration needed:
class Vector;
struct Vertex : public dl32AdditionHelper<Vertex , Vector , true>, //The last parameter is used to enable operator+ simmetry. That is, this covers cases 3 and 7.
public dl32SubstractionHelper<Vertex , Vector , false>, //This covers case 4 (Simmetry si not enabled, see note bellow).
{
float x , y;
//For Vertex + Vector = Vertex
Vertex& operator+=(const Vector& other)
{
x += other.x;
y += other.y;
return *this;
}
//For Vertex - Vector = Vertex
Vertex& operator-=(const Vector& other)
{
x += other.x;
y += other.y;
return *this;
}
};
struct Vector : public dl32AdditionHelper<Vector>, //This covers case 5.
public dl32SubstractionHelper<Vector>, //This covers case 6.
{
float x , y;
//For Vector + Vector = Vector
Vector& operator+=(const Vector& other)
{
x += other.x;
y += other.y;
return *this;
}
//For Vector - Vector = Vector
Vector& operator-=(const Vector& other)
{
x += other.x;
y += other.y;
return *this;
}
};
Thats all.
Symmetry note: Symmetry property implies that operation a # b its equal to b # a, for a given operator #. Arithmetic helpers uses this feature to provide symmetric operators.
For example, matrix algebra: m1 + m2 == m2 + m1, so operator+(const matrix_type_2& m1 , const matrix_type_1& m2) is implemented as m2 + m1 (A call to operator+(const matrix_type_1& m1 , const matrix_type_2& m2)). As you can see, symmetry not works for case 8.
My helpers implementation uses the type of the first parameter as return type of the operator. This is the reason why your other cases are not covered. But that cases implies a conversion from Vector to Vertex or/and viceversa. If you modify the implementation to do that, your all cases could be covered.
Forward declaration actually solved my problems. The compiling issue I got was because my function signatures didn't match correctly in a not obvious way.

Overloading operator order [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Operator Overloading in C++ as int + obj
Operator overloading c++-faq
I have a Point object with this operator:
Point operator +(float other) const {
return Point(x + other, y + other, z + other);
}
I can perform addition like so:
point + 10
But I can't perform it in reverse order:
10 + point
Is there another operator I need to overload in order to provide this functionality?
You normally want to overload the global operator:
Point operator+(Point const &a, float b);
Point operator+(float a, Point const &b);
Instead of two overloads, you may want to use only one overload:
Point operator+(Point const &a, Point const &b);
and then have a ctor to create a Point from a float:
class Point {
public:
Point(float);
};
In this case, adding a float to a Point will use the ctor to convert the float to a Point, then use your overloaded operator+ to add those two Points together.
As a free function:
Point operator+(float other, const Point &pt) {
return pt+other;
}
Given an existing Point& Point::operator+=(float other), add these two free functions:
Point operator+(Point pt, float other) {
return pt += other;
}
Point operator+(float other, Point pt) {
return pt += other;
}
Outside of the class:
inline Point operator+(const float& other, const Point& pnt) { return Point(...); };

How do I most efficiently return multiple values from an overloaded operator? (C++)

I have a class "complex" that contains a Real and an Imaginary value. I'm trying to overload the + operator so I can add real to real and imaginary to imaginary, but I'm banging my head against a wall here.
In the function, I can get the values easy. Returning them however, is a bitch.
My plan is to overload the '=' operator, too, so I can go
complex a, b, c;
(set a and b)
c = a + b;
then have a+b return a complex, then have complex c equal the complex returned by a+b
Any opinion on whether that's a viable path?
Any opinion on whether it can be done easier?
Return them as a complex! e.g.
const complex operator+(const complex &a, const complex &b)
{
return complex(a.re + b.re, a.im + b.im);
}
You shouldn't need to overload operator=; the compiler will generate one for you that does an element-by-element copy, which will probably suffice for a complex class.
I'm not sure I understand the problem. Do you have a complex class?
struct complex
{
complex(float real, float imag) :
real(real), imag(imag)
{}
// first make the mutating version
complex& operator+=(const complex& rhs)
{
real += rhs.real;
imag += rhs.imag;
return *this;
}
float real, imag;
};
// then use that for the non-mutating version
complex operator+(complex lhs, const complex& rhs)
{
lhs += rhs;
return lhs;
}
This is, of course, just an exercise; we have std::complex.
What's wrong with overloading the + operator:
complex operator+(const complex& a, const complex& b) const {
return complex(a.real + b.real, a.imag + b.imag);
}
And the operator=() similarly? (but the compiler give you this by default)
complex& operator=(const complex& a) {
real = a.real;
imag = a.imag;
return *this;
}
It is viable but there is already complex class in standard library. Reuse it or at least have a look how the operator overloading is done there.

Handling large numbers in C++?

What is the best way to handle large numeric inputs in C++ (for example 10^100)?
For algorithms I usually switch over to ruby and I sometimes use strings.
Any other good methods?
It sounds like you're looking for a way to enter Arbitrary Precision numbers.
here are two libraries you could use: GMP and MAPM
Check out The Large Integer Case Study in C++.pdf by Owen Astrachan. I found this file extremely useful with detail introduction and code implementation. It doesn't use any 3rd-party library. I have used this to handle huge numbers (as long as you have enough memory to store vector<char>) with no problems.
Idea:
It implements an arbitrary precision integer class by storing big int in a vector<char>.
vector<char> myDigits; // stores all digits of number
Then all operations related to the big int, including <<, >>, +, -, *, ==, <, !=, >, etc., can be done based on operations on this char array.
Taste of the code:
Here is the header file, you can find its cpp with codes in the pdf file.
#include <iostream>
#include <string> // for strings
#include <vector> // for sequence of digits
using namespace std;
class BigInt
{
public:
BigInt(); // default constructor, value = 0
BigInt(int); // assign an integer value
BigInt(const string &); // assign a string
// may need these in alternative implementation
// BigInt(const BigInt &); // copy constructor
// ~BigInt(); // destructor
// const BigInt & operator = (const BigInt &);
// assignment operator
// operators: arithmetic, relational
const BigInt & operator += (const BigInt &);
const BigInt & operator -= (const BigInt &);
const BigInt & operator *= (const BigInt &);
const BigInt & operator *= (int num);
string ToString() const; // convert to string
int ToInt() const; // convert to int
double ToDouble() const; // convert to double
// facilitate operators ==, <, << without friends
bool Equal(const BigInt & rhs) const;
bool LessThan(const BigInt & rhs) const;
void Print(ostream & os) const;
private:
// other helper functions
bool IsNegative() const; // return true iff number is negative
bool IsPositive() const; // return true iff number is positive
int NumDigits() const; // return # digits in number
int GetDigit(int k) const;
void AddSigDigit(int value);
void ChangeDigit(int k, int value);
void Normalize();
// private state/instance variables
enum Sign{positive,negative};
Sign mySign; // is number positive or negative
vector<char> myDigits; // stores all digits of number
int myNumDigits; // stores # of digits of number
};
// free functions
ostream & operator <<(ostream &, const BigInt &);
istream & operator >>(istream &, BigInt &);
BigInt operator +(const BigInt & lhs, const BigInt & rhs);
BigInt operator -(const BigInt & lhs, const BigInt & rhs);
BigInt operator *(const BigInt & lhs, const BigInt & rhs);
BigInt operator *(const BigInt & lhs, int num);
BigInt operator *(int num, const BigInt & rhs);
bool operator == (const BigInt & lhs, const BigInt & rhs);
bool operator < (const BigInt & lhs, const BigInt & rhs);
bool operator != (const BigInt & lhs, const BigInt & rhs);
bool operator > (const BigInt & lhs, const BigInt & rhs);
bool operator >= (const BigInt & lhs, const BigInt & rhs);
bool operator <= (const BigInt & lhs, const BigInt & rhs);
If you wish to make your own code for the purpose try using strings to store big numbers... you can then create basic ops like + - / * on them... for example -
#include <iostream>
using namespace std;
string add (string &s1, string &s2){
int carry=0,sum,i;
string min=s1,
max=s2,
result = "";
if (s1.length()>s2.length()){
max = s1;
min = s2;
} else {
max = s2;
min = s1;
}
for (i = min.length()-1; i>=0; i--){
sum = min[i] + max[i + max.length() - min.length()] + carry - 2*'0';
carry = sum/10;
sum %=10;
result = (char)(sum + '0') + result;
}
i = max.length() - min.length()-1;
while (i>=0){
sum = max[i] + carry - '0';
carry = sum/10;
sum%=10;
result = (char)(sum + '0') + result;
i--;
}
if (carry!=0){
result = (char)(carry + '0') + result;
}
return result;
}
int main (){
string a,b;
cin >> a >> b;
cout << add (a,b)<<endl;
return 0;
}
Are you looking for how to perform operations on the large inputs you receive? There is a big integer C++ library (similar to Java) that allows you to perform arithmetic operations...
assuming you are talking about inputting numbers, double precision would get you up to 1.7976931348623157 x 10^308
You might want to have a look to gmplib, an arbitrary precision number handling library for C and C++
If you want it to be accurate, you need a library made to deal with big numbers. Java has BigInt that will always be accurate no matter how many digits you want to take it to, and provides math operations on them. All the source code is included, you could transfer it, but this really isn't the kind of thing C++ is best at--I'd use a JVM based language and use one of the Big libraries.
I don't think I'd use ruby for this unless you wanted it to be slow, and I'm assuming that since you are talking about C++, speed is somewhat of a design consideration.
As others have already pointed out, there are various bignum/arbitrary precision libraries in C++ that you would likely find useful. If speed isn't necessary, I'm under the impression that Python and Lisp both use bignums by default.
Consider boost::cpp_int
#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
int main()
{
using namespace boost::multiprecision;
cpp_int u = 1;
for(unsigned i = 1; i <= 100; ++i)
u *= i;
// prints 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 (i.e. 100!)
std::cout << u << std::endl;
return 0;
}
Well I think the best way to do such arithmetic calculation is by using strings. Give input as command line arguments and then manipulate the whole logic using string functions like atoi() and itoa()! But, hey can this be done for multiplication and Division? I think in this way strlen of strings entered doesn't matter for programming for compiler until the logic is fine.