Overloading ++ operator - c++

I need to overload operators for a class of complex numbers
with 2 private members :
double real;
double imag;
this is the constructor
complex::complex(double a, double b) {
real = a;
imag = b;
}
This is the given prototype
complex complex :: operator++ (int x);
but I don't see how this would be overwritten since
int u = 1;
int h = 3;
u++3;
doesn't work
so how would this compile
I've only ever seen
variable++
--variable
How would this be overloaded?

The int x in the post-increment operator signature operator++(int x) is called a dummy parameter. It doesn't actually mean anything, other than to distinguish this from operator++() which is the pre-increment operator.
In the body of the function you write the logic for post-increment but just don't use x. It gets value 0 when you use variable++.
Technically you could write variable.operator++(5); and then the post-increment operator would be called with x being 5 but there's no real reason to want to do that.

Related

Operator overloading with different datatypes in C++

Take this for example:
float operator+(int a, float b)
{
Return b + (float)a;
}
void main()
{
int a = 10;
float b = 2.5f;
float c;
c = a + b; //works as intended
c = b + a; //results in type mismatch error
}
So my question:
Is there a way to have the parameters being accepted bidirectional without defining a second function?
It is not possible to overload operators for fundamental types.
You should only overload operators for classes that you have defined.
A solution for overloading a binary operator for your own class with heterogeneous arguments symmetrically, is to define the operator for first type, and make the second type implicitly convertible to the first.
Use float 'a' instead of int 'a',In default when adding int number to float it automatically assign higher precision. (Int + float outcome become float)

About the C++ overloaded operators

Running the program below on my computer
#include <iostream>
class Int {
public:
Int(int x) : val{x} {}
Int operator++() {
std::cout << "Int::operator++()\n";
return ++val;
}
friend Int operator+(Int a, Int b) {
std::cout << "operator+(Int, Int)\n";
return a.val + b.val;
}
friend Int operator*(Int a, Int b) {
std::cout << "operator*(Int, Int)\n";
return a.val * b.val;
}
private:
int val;
};
int main()
{
Int a = 1, b = 2;
b = ++a + b * b;
return 0;
}
I got this output:
operator*(Int, Int)
Int::operator++()
operator+(Int, Int)
As far as I known, the prefix ++ has higher precedence than binary *. But in the output shown above, the prefix ++ is called after the binary *! Is it because the compiler treats the operator+ as a function call (which leads to Unspecified Behavior)? Can I always consider an overloaded operator as a function (which makes the behavior of x = x++ well-defined when x is an Int)?
Thanks!
Is it because the compiler treats the operator+ as a function call (which leads to Unspecified Behavior)?
Yes. But note that it doesn't matter if ++a is evaluated after b * b, because in the end, those two are added correctly, which respects operator precedence rules.
Your expression without the assignment is equivalent to:
operator+(a.operator++(), operator*(b, b))
The order of evaluation of function arguments is unspecified, so technically, ++a can be evaluated before b * b, but also the other way around.
Can I always consider an overloaded operator as a function (which makes the behavior of x = x++ well-defined when x is an Int)?
Yes and no. If Int does the same thing as the "normal" operators would do, then no (until C++17), because that would be undefined behavior. But if Int doesn't change x in x++ for example, then yes.
As far as I known, the prefix ++ has higher precedence than binary *.
Higher precedence doesn't mean that the prefix increment will be called before the multiplication operator, but in which order the parameters are bound to the corresponding operation.

Why is & needed for member function pointers, not for normal function pointers?

I understand my second statement that "why & is not needed for normal function pointers" because function name itself is address of the function.
What I do not understand is why '&' is strictly needed for member function pointers?
Examples:
Normal function pointers:
int add(int a, int b) {
return (a + b);
}
int (*fp)(int, int);
fp = add;
(*fp)(2, 3) // This would give me addition of a and b, i.e. 5
Member function pointers:
class ABC {
public:
int i;
ABC() { i = 0; }
int addOne(int j) {
return j + 1;
}
};
// Member function pointer
int (ABC::*mfp)(int);
// This is what I am talking about. '&' in below line.
mfp = &ABC::addOne;
ABC abc;
std::cout << (abc.*mfp)(2) << std::endl;
It seems to me that the address-of operator is necessary for member function pointers because the right-hand side (rhs) of the declaration is a constant rather than a variable.
We wouldn't say
int (ABC::*mfp)(int);
mfp = ABC::addOne();
because that would be to invoke a function.
Furthermore, the scope resolution operator :: has the highest precedence in the C++ table of operator precedence:
https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/cpp-built-in-operators-precedence-and-associativity.md
The :: operator is evaluated before any other operators are on the rhs. I suppose the complier wonders "Hmmmm...what's that? That should be a function, but..." and then sees the address-of operator and knows what the developer needs.

What does operator float*() do?

I have been looking through source code trying to learn more about C++ and I came across some code that looked confusing. I haven't been able to figure out its use by playing around with it.
Please can someone explain what the operator float *() does and how it is used?
class Vector
{
public:
float x,y,z;
Vector() : x(0), y(0), z(0){
}
Vector( float x, float y, float z ) : x(x), y(y), z(z){
}
operator float*(){
return &x;
}
operator const float *(){
return &x;
}
I have searched StackOverflow and it looks like it is a conversion operator but I am still unsure what it actually does and why it is useful.
Kind regards,
operator type_name declares an implicit conversion operator. In other words, this function is called when you are attempting to (implicitly) convert an object of your type to float* – for instance in an assignment:
Vector x(1, 2, 3);
float* f = x;
assert(*f == 1);
Needless to say, this particular conversion is quite terrible because its effect is pretty unintuitive and easily results in impossible to find bugs. Implicit conversions should generally be handled with care since they hide potentially confusing semantics. But they can be used well with types which are supposed to be used interchangeably, and where a conversion doesn’t hurt.
For instance, consider the case where you write your own integer and complex classes. A conversion from integer to complex is harmless, since every integer is a complex number (but not vice-versa). So having an implicit conversion integer → complex is safe.
As it was said it is a conversion operator that converts an object of type Vector to an object of type float *. This conversion operator can be called implicitly because it has no function specifier explicit.
I think that the idea of introducing this operator was to access data members x, y, z as an array of floats. In this case you could apply some standard algorithms to an object of the class converting it to an array of floats.
Take into account that the second overloaded operator-function shall have qualifier const.
Consider the following code
#include <iostream>
#include <algorithm>
class Vector
{
public:
float x,y,z;
Vector() : x(0), y(0), z(0){
}
Vector( float x, float y, float z ) : x(x), y(y), z(z){
}
operator float*(){
return &x;
}
operator const float *() const {
return &x;
}
};
int main()
{
Vector v( 1, 3, 2 );
auto max = std::max_element( v + 0, v + 3 );
std::cout << *max << std::endl;
return 0;
}
The output is 3.
Take into account that according to the C++ Standard
13 Nonstatic data members of a (non-union) class with the same access
control (Clause 11) are allocated so that later members have higher
addresses within a class object
So the order of the data members of the class is defined.
It's a conversion operator allowing the class to be used with APIs that want a float*.You have two different versions because one will convert the class to a const float* and the other to a non-const. The non-const conversion operator breaks your class's encapsulation though.
Usefulness: Well it can be very handy when, as I mentioned, you want to work with a library that expects a certain type. It can also be useful when there is a natural conversion between two types.

How to overload "operator %" in c++

I want to overload the % operator in c++, in order to avoid editing a huge block of code by hand. I tried this:
static float operator %(const float& left, const float& right);
In my header, but it wont work because "nonmember operator requires a parameter with class or enum type".
I'm relatively new to C++, what am I supposed to do?
Operator overloads must have at least one of their arguments as a user-defined type. So you cannot do this.
What that means is that you cannot overload an operator when all the operands are non-class/enum types. i.e., you cannot override the behaviour of % when both sides are float (or int, or any other primitive type).
As has already been stated, you cannot define overloaded operators for intrinsic types.
However, if you are willing to take advantage of implicit type conversion you can achieve something close to what you require with a single cast to one of your floats on a wrapper type that implements an overloaded% operator.
class FloatWrapper
{
private:
float m_Float;
public:
FloatWrapper(float Value):
m_Float(Value)
{
}
friend float operator%(const FloatWrapper& lhs, const FloatWrapper& rhs)
{
//your logic here...
return (int)lhs.m_Float % (int)rhs.m_Float;
}
};
int main()
{
float Value1 = 15.0f;
float Value2 = 4.0f;
float fMod1 = (FloatWrapper)Value1 % Value2;
float fMod2 = Value1 % (FloatWrapper)Value2;
return 0;
}
class Test
{
public:
float operator%(float);
};
In C++ you need not to declare the operator as static, as opposed to C#. The argument can be of any type and the return value can also be. The first type would be the class itself.
Example:
Test test;
float x = test % 10.2f;