Pointer to member operator - c++

I have this link http://www.codingunit.com/unary-and-binary-operator-table. It says that pointer to member operator is a binary operator.
I have this code :
class test
{
public:
int num;
test(int j)
{
num=j;
}
test* operator->()
{
this->num;
}
};
int main()
{
test T(5);
cout<<"Number is :"<<T->num;
}
As I know, non static member function of binary operator accepts one argument, but according to this program if I provide it one argument. It has an error, which says that test* operator ->(int x) should be test* operator ->(void) .

To get the expected result, you need to change your program as follows:
test* operator->()
{
return this;
}
};
int main()
{
test T(5);
cout<<"Number is :"<<T->num;
}
In your operator overloading function, you should return this pointer. Since your operator overloaded function for -> does not accept a parameter, so when you call it you don't need to pass a parameter value. So function call should be T->num;

Related

Question about overloaded operator T() in C++ template class

I have this little piece of code:
template<typename T>
class Test
{
public:
//operator T() const { return toto; }
T toto{ nullptr };
};
void function(int* a) {}
int main(int argc, char** argv)
{
Test<int*> a;
function(a);
return 0;
}
It doesn't compile unless the line operator T() const { return toto; } is un-commented. This magically works, but I am not sure why (if I un-comment the line).
I do understand that if the line is commented, the type of a when passed to function() is incompatible with the expected type int*. So, of course, the compiler complains ... no problem.
I also understand that the operator returns the actual type of the object, therefore in this particular case the compiler is happy.
I don't understand why the operator is called in this particular case.
Is doing function(a) the same thing as doing function(a()), only the () are implicit?
operator T() const { return toto; } is a user defined conversion operator, it is not operator(). It's used to define that your class is convertible to a different type.
operator() would look like this instead:
void operator()() const { ... }
In your case, you are using int* as T. If you substitute it yourself in the operator, you will see that it becomes operator int*() const { return toto; } which means "my class can be converted to an int* and the result of that conversion is evaluated as return toto;".
The function function() only accepts an int* as its argument. When you provide a Test instance, the call is only legal if there is a way to convert from Test to int*, which is why the operator T is required for the code to compile.

Object reading and writing overload in C++

I know that the assignment operator can be overloaded. When writing to an object, the object's overload function is called.
Obj = 10; // Obj's assignment overload function called.
Is there a way to define a function to be called when an object is read?
int a = Obj;
In this case Obj's reading function would be called and the return value would be assigned to a.
You're looking for what's sometimes called a cast operator.
example:
#include <iostream>
struct example
{
int val;
operator int() const { return val; }
};
int main ()
{
example x{42};
int y = x;
std::cout << y;
}
Will print 42.

Why in below code return type is class type used for operator overloading?

I have been trying to understand operator overloading and did not get the use of return type as class type in the below program:
When I switch "overload" return type with "int" it works fine.
#include <iostream>
using namespace std;
class overload {
private:
int count;
public:
overload(int i)
: count(i)
{
}
overload operator++(int) //why return type is class type when i can use int
{
return (count++);
}
overload operator++() //why return type is class type when i can use int
{
count = count + 1;
return count;
}
void Display()
{
cout << "Count: " << count<<endl;
}
};
// Driver code
int main()
{
overload i(5);
overload post(5);
overload pre(5);
// this calls "function overload operator ++()" function
pre = ++i;
post = i++;
i.Display();
return 0;
}
The difference between the pre/post increment operators is that one works on the object directly (pre-increment: ++foo), and one needs to take a copy of the object and return that (post increment: foo++). A slightly more verbose way of writing this would be:
// return a new object that represents the old value
overload operator++(int)
{
overload oldValue(count); // take copy
count++; // increment this object
return oldValue;
}
// increment the count, and return a reference to this object
overload& operator++()
{
++count;
return *this;
}
Whilst you could return int (don't do that!), it will only lead to confusion. Effectively it would cause a few issues with code such as:
overload foo = ++someOtherFoo;
Which if you were to return int from ++, would effectively end up calling your constructor function (rather than copy constructor) to construct a new object. i.e.
overload foo = overload(++someOtherFoo);
That constructor might not be available, and so the code would fail.
If you want your object to automatically convert itself to an integer, then the correct way would be to overload the cast operator, e.g.
operator int () const
{
return count;
}
There are no restrictions on the return type of an overloaded operator. Here it can be int as well.
The code you show has the class type as return type to facilitate the other statements in the code as below if ever the constructor of the overload class is marked explicit;
For example with:
explicit overload(int i)
: count(i)
{
}
and
int operator++(int) //return type is int
{
return (count++);
}
int operator++() //return type is int
{
count = count + 1;
return count;
}
The following will fail to compile:
pre = ++i; //will not work
post = i++; //will not work
This is because the implicit copy assignment operator will no longer be viable for conversion from int to const overload.
See Demo
Note that the Canonical implementations of the prefix and postfix increment/decrement operators return overload& and overload respectively.
Although canonical form of pre-increment/pre-decrement returns a reference, as with any operator overload, the return type is user-defined; for example the overloads of these operators for std::atomic return by value

What does *this = NULL mean inside a method in a templated class?

Inside a templated class, I found the expression, *this = NULL What does such an expression mean ?
The following is its definition:
TYPE** getPtr()
{
*this = NULL;
return &m_pPtr;
}
where m_pPtr is type TYPE* in the template class.
Assignment operator:
// Assignment operator.
TYPE* operator =(TYPE *pPtr) {
if (pPtr == m_pPtr)
return pPtr;
m_pPtr = pPtr;
return m_pPtr;
}
Vishnu.
It's difficult to say what the point of such a statement is without seeing the actual code.
But it will probably be invoking an overloaded assignment operator. e.g.:
#include <iostream>
class X {
public:
void operator=(void *) {
std::cout << "Here!\n";
}
void foo() {
*this = NULL;
}
};
int main() {
X x;
x.foo();
}
It's attempting to assign 0 to the current object. It will call something like
operator=(void *);
Another possibility (as far as I know) is that there is a constructor in the object which takes a void* or similar type. Then it would construct an object and then copy-assign that.
T :: T(void *); // construct with the void *
T :: T(const T &); // copy assignment

How do I create a class that can initialize C++ data types?

The title basically says it all. I mainly want to do this so that I can create an object (say, a custom string object) that can initialize the parameters of other functions in other APIs. Here's an example of me trying to get a custom integer class to work:
#include <iostream>
using namespace std;
class test
{
public:
int member;
test(int i) : member(i) {}
friend int &operator=(int &i, test t);
};
int &operator=(int &i, test t)
{
return (i = t.member);
}
int main()
{
int i;
test t = 90;
cout << (i = t);
return 0;
}
Unfortunately I receive an error saying that operator= needs to be a member function. I understand the C++ standard's goal in preventing static and non-member overloads for the assignment operator from being implemented, but is there any other way to do this? Thanks for any help/suggestions!
This is not done with an assignment operator but with an overloaded typecast. This would make your main function work like expected:
#include <iostream>
using namespace std;
class test
{
public:
int member;
test(int i) : member(i) {}
operator int() const {return member;}
};
int main()
{
int i;
test t = 90;
cout << (i = t);
return 0;
}
What you are trying to do needs an conversion operator
operator int()
{
return this->member;
}
For the class you are trying to write(containing only integer members), You do not need to overload the = operator.
= operator is one of the member functions that is generated by the compiler by default for every class. Caveat is, it does a simple bit by bit copy(shallow copy) of class members, since you have only integers it should be good enough for you.
You would need to overload the = operator if you had dynamically allocated pointers as member functions, because in that case a shallow copy of those pointers would result in all the objects containing a member pointer pointing to the same dynamic memory location & if one of the object finishes it lifetime, other objects are left with a dangling pointer.
As #Tony, aptly points in out comments Shallow copy is usually bad but not always. See his comments for a scenario.
If at all you want to overload the assignment operator check out the Copy and Swap Idiom to do it right way.
You should also check out the Rule of Three.
Try this:
class test
{
public:
int member;
test(int i) : member(i) {}
operator int() {return this->member;}
};
int main(void)
{
int i;
test t = 90;
cout << (i = t);
return 0;
}
The assignment operator cannot be a friend function. The assignment operator can only be declared as a non-static member function. This is to ensure that it receives the L-value as its first operand. The same is true for the [], (), and -> operators. In your case, since int is an build-in type, you cannot use member function. You can implement operator int() to cast your user-defined type to int.