I Have a Fraction Class.
I need to do 3 operations on Fraction Object i.e
Multiply two Fraction objects. e.g F1*F2
Multiply a Fraction object by an integer. For ex. F1*3
Multiply an integer by a Fraction object. For ex. 3*F1.
The first two case can be achieved by overriding the Fraction Class * operator.
Fraction operator*(const Fraction&);
Fraction operator*(const int&);
but how to multiply an integer by a fraction Object? The third case
Any Suggestions??
PS: I don't want to treat integer as a Fraction object e.g (3/1) and then doing the multiplication.
You need to implement the operator overload as a free function, like this:
Fraction operator *(int lhs, Fraction rhs)
{
rhs *= lhs;
return rhs;
}
Note that I have implemented the function in terms of Fraction::operator*=(int) (see here why this is considered good practice). If this function is not present, you might want to pass the second parameter as const Fraction& rhs and provide a different implementation.
Besides, note that an idiomatic way to handle this scenario is to allow an implicit construction of Fraction instances by a single int argument, so your constraint seems a bit awkward to me. Further note that users of your Fraction class might expect all arithmetic operations to be possible (why should there be operator*, but not operator/?). To reduce the amount of manual code to be written in such cases, the boost operator library can be of great help.
Can I make a case for the inplace friend function?
In c++11 you can declare and write your friend function inside the class, which can make it much neater:
class MyNumber
{
private:
Clever c;
Clever Multiply (Clever, i) { ... }
public:
MyNumber operator * (int i)const { return Multiply(c,i) }
MyNumber operator * (const MyNumber &i)const { ... }
const MyNumber& operator *= (int i) { return c= Multiply(c, i); }
// introducing the inline friend (presuming multiply is commutative/symmetric here)
friend MyNumber operator (int i, const MyNumber& j) { return j.Multiply(c,i); }
};
Note that this friend function is still actually a global function, and has access to the class internals, but its implementation is now tidily inside the class definition.
The neatness of this style is such that I am tempted to use it even when I don't actually need the dirty friend access.
With these math overloading objects, also consider the RValue substitution overloads. An rvalue implementation of binary multiply implemented as mult-assign can show some efficiencies, though perhaps not soo much with only a 2-value fraction class.
There are three different ways to overload operators: the member function way, the friend function way, and the normal function way.
In this specific case we need overload the operators in friend function way.
friend Fraction operator*(const Fraction &a, const Fraction &b); //F1*F2
friend Fraction operator*(const Fraction &a, int b); //F1*3
friend Fraction operator*(int a, const Fraction &b); //3*F1
Related
Suppose I have a class called Complex, why I'm allowed to define the following function:
Complex operator+(Complex& c1, Complex& c2);
But I can't write:
Complex operator**(Complex& c1, Complex& c2);//for power
** is not a valid C++ operator on its own, it is simply two * operators with no whitespace. We cannot create new operators in C++, but operator* can be overloaded as an unary or a binary operator. operator* can be implemented as a non-member function, member function, or friend function, depending on the class structure. Below is an example of operator* implemented as a binary, non-member function, which returns a new Example object.
struct Example {
int x;
};
Example operator*(Example a, const Example& b){
return a *= b;
}
From over.oper, you can see which operators can be overloaded. You will notice that ** is not one of the valid operators to overload. There is, however, the ^ operator you can use (although it's usually meant for bitwise)
As mentioned in the comments, you cannot create new operators this way, so you cannot make a new one for **
I am trying to operator overload for a complex number, I have implemented a class where it takes in real and imaginary part. I am trying to overload the % operator where it return a modulus value(length of the real and imaginary), but I am getting error "must take exactly one argument", What am I doing wrong?
Here is my header file
complex.h
class complex{
private:
double rm;
double im;
public:
void operator % ();
complex.cpp
void operator %(){
complex c;
c.re = pow(re,2);
c.im = pow(im,2);
return c;
Thank you!
The '%' operator in C++ is a binary operator, like a % b, but you are trying to use it like a unary one. C++ allows you to overload the implementation of existing operators, but not add new ones or change how existing ones are used.
operator% is a binary operator (some, like operator- can be unary or binary).
This means that you can define it in two different ways.
As a standalone function
complex operator%(const complex& left, const complex& right);
As a class member function, in which case the 'left' term is implicitly this
complex& complex::operator%(const complex& right);
I see a few more issues with your code. Usually in C++ % means the modulus or remainder. With complex numbers the modulus is the norm implemented in abs and it returns a real. I guess this is to make things clearer, especially when there are expressions that mix complex and real numbers. In your modulus operator you are simply squaring the real and imaginary components. I'm not sure what this is supposed to mean.
As mentioned, the % operator is a binary operator so repurposing it as a unary modulus is not possible.
Having said that, we can abuse the free function binary operator in order to provide syntactic sugar.
Note This answer is for fun and in the spirit of learning. It is not a recommendation of a coding style.
#include <cmath>
struct imperative_mode_sentinel {};
struct complex
{
complex(double rm, double im) : rm(rm), im(im) {}
double rm, im;
complex modulus() const
{
return complex(std::pow(rm, 2), std::pow(im, 2));
}
};
auto operator%(imperative_mode_sentinel, complex const& r) -> complex
{
return r.modulus();
}
constexpr static auto imperative_mode = imperative_mode_sentinel();
int main()
{
auto c = complex(1,1);
auto d = imperative_mode %c; // equivalent to d = c.modulus()
}
If this is your modulus operator, it is fine. you can give it whatever meaning you want. See;
Other than the restrictions above, the language puts no other
constraints on what the overloaded operators do, or on the return type
(it does not participate in overload resolution), but in general,
overloaded operators are expected to behave as similar as possible to
the built-in operators
class complex{
private:
double rm;
double im;
public :
complex(int i, int r) {
re = r; im = i;
}
complex operator%(const complex& mc){//for complex
return complex(pow(re,2),pow(im,2)) ;
}
};
I'm implementing a fraction class, and need to overload arithmetic operators.
The problem is, can I only implement a const version.
For example, addition:
Fraction operator+( const Fraction& other ) const;
Since both non-const, and const Fraction objects can call this function, do I still need to have an non-const operator+ member function?
const member functions can be called on non-const objects, so no, you don't need a non-const overload.
Fraction a, b;
Fraction c = a + b; // no problem
In general, this kind of problem is better solved with a member operator+= and a nonmember operator+, like this:
class Fraction {
public:
const Fraction& operator+=(const Fraction&);
};
Fraction operator+(const Fraction& lhs, const Fraction& rhs) {
Fraction res(lhs);
res += rhs;
return res;
}
No. You can call const methods over non-const objects, exactly as you can have const references bind to non-const objects. IOW, you can always pass an object that you can modify to code that promises not to modify it - there's no loss of safety. The opposite of course is not true - if you have a const object (=> an object you promised not to modify) you cannot pass it to code that doesn't adhere to this promise.
The other day, I ran into trouble when I tried to overload a two-parameter operator with the use of a class member function. I tried references, but nothing changed. The compiler said I couldn't write a member function that takes more than one argument of the same type as the class itself. Why is that?
Here is the code:
class Fraction
{
public:
Fraction(int num=1, int den=1): numerator(num), denominator(den) {}
Fraction(const Fraction& r): numerator(r.numerator), denominator(r.denominator) {}
Fraction& operator=(const Fraction&);
Fraction& operator*(const Fraction&, const Fraction&);
private:
int numerator, denominator;
};
Fraction& Fraction::operator=(const Fraction& r)
{
numerator = r.numerator;
denominator = r.denominator;
return *this;
}
Fraction Fraction::operator*(const Fraction& x, const Fraction& y)
{
Fraction z(x.numerator*y.numerator, x.denominator*y.denominator);
return z;
}
The following is the error message from the compiler:
Fraction& Fraction::operator*(const Fraction&, const Fraction&)' must take either zero or one argument
The operators take a fixed amount of arguments, for example operator+ as the addition operator takes exactly 2 parameters. If it is a member function the first(leftmost) is implied to be this and the second is passed as a parameter.
What would calling an operator+ that took three parameters look like? One might imagine it would look like 3 + 4 + 5 but that is the equivalent of calling operator+(3,4) then operator+(7,5).
For a list of operators and how many arguments they take please check out wikipedia: http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
For more details there is another StackOverflow post that goes into great detail: Operator overloading
Firstly, the issue you are observing has absolutely nothing to do with member functions in general. Member functions can generally take arbitrary number of arguments of "same class" type. In your example you can declare
class Fraction
{
void foo(Fraction &f1, Fraction &f2, Fraction &f3, Fraction &f4) {}
...
};
without any problems. So, it is not clear why you decided to word your question as if it is about member functions in general.
Secondly, in your code it is really about the simple fact that you are trying to overload an operator. Operator syntax in C++ is fixed for most (but not all) operators. This immediately means that those operators whose syntax is fixed will have fixed number of parameters.
In your example, it is operator *. It can be unary (one parameter) or binary (two parameters). When you overload this operator by a member function one parameter is already implied, so you can only add zero or one additional parameters (for unary * and binary * respectively). You, on the other hand, are trying to add two more parameters in additions to the implicit one. I.e. you are trying to define a ternary operator *. This is not possible. There's no ternary * operator in C++. And this is exactly what the compiler is telling you.
I have a Fraction class, works fine within its own yard, like 1/2+1/3=5/6 or even with int,1/2+2=5/2.
It is okay for me to see 3/2+3/2=3/1, however, is there a way to return a type conditioned? For example, if the denominator is 1, it returns an int, otherwise returns a Fraction.
If not possible, any other detour?
class Fraction{
__int64 _num,_dem;
public:
friend Fraction const operator+(Fraction const& lhs,Fraction const& rhs);
}
Fraction const operator+(Fraction const& lhs,Fraction const& rhs){
return Fraction(lhs)+=rhs;
}
thanks a lot for any advice!
You can't conditionally change the return type. (You could have polymorphism if you had a super class, but that's not what you're asking for here since int is an intrinsic type.) Consider this case:
Fraction A, B;
// initialize to 3/2 and 3/2
sometype C = A + B;
What is the type of C? The compiler must know. Even in cases of polymorphism or type inference, there must be a deterministic solution at compile time as to what the type of C is.
And there's no way to know whether the Fraction represents a whole number until runtime.
No, it's not possible in C++ to have the return type depend on the values of the operands in the way you're hoping for. What would be the point anyway, since the next layer of code out from there will need to know statically what the result type is?
Now, if your values are all known at compile time, you can do some template magic to make things happen during compilation, but that doesn't seem to be what you're trying to accomplish.
A possible (runtime) solution is to have implicit convertion operator to int that assert that your fraction is x/1.
class Fraction
{
operator __int64() const
{
assert(den == 1);
return num;
}
}
It will allow you to pass Fraction to integers and check at runtime that it is correct.
Not maybe what you exactly want, but this is the best you can have.
A possible solution would be an amalgamation of std::pair and boost::optional.
std::pair< boost::optional<Fraction>, boost::optional<int> > const operator+(Fraction const& lhs,Fraction const& rhs);