Hello again! In this video, we are going to look at member and non-member operators. When we are writing
an overloaded operator.
We can usually implement it either way: as a member function or a non-member function.
If you can, you should implement it as a member function.
This will provide direct access to the private data. It is a member function, so we do not need any friends
or delegate member functions.
And also, it keeps all the code that is related to the class together, in the class definition.
There are some operators which work better as non-member functions. And there are a few which cannot be implemented
as member functions at all.
The problem with having operators as member functions arises with binary operators. If we
want a type conversion - actually, let's look at this in the IDE.
So here is our String class again,
with a capital 'S'. We have briefly gone back to using the library string as the member, to keep things simple.
I have added a constructor which takes a C-style string, because we are going to use one of those.
We have a plus operator as a member function.
This will take another object of the same class. And it will add the library string member to our own library string
member, and return the result.
We have the member function for printing out the member.
And in our main() function, we create a couple of objects of this class. And then we try out our new operator.
So if both the arguments are objects of our class, it works fine.
This is actually called as a member function call. So this will call the member function on "w", operator plus, with
"bang" as the argument.
So this will add the library string inside "w" to the library string inside "bang".
And that all works. If we have a string object with data "world" and one with an exclamation mark, then we get
"world", exclamation mark.
The problem arises is if we want to use a string conversion. We have a constructor which can convert
C-style string into one of our Strings with a capital 'S'.
The problem is, we only have a member function. And you cannot call a member function on a C-style string.
So this is going to give a compiler error.
There we are. No global operator found. So the compiler could not work out how to call this member function
from the C-style string, and it looked for a non-member operator plus. But, because we implemented
the operator as a member function, there is no suitable non-member function.
So that is the problem that can arise.
If we use a non-member function, so the operator plus is defined outside the class, then it all works.
The call to the plus operator is the call to a non-member function, with arguments "w" and "bang", and the
compiler will convert function arguments if it can.
So in this case, it is going to convert the C-style string "Hello" to a String with a capital 'S', by
calling that constructor, and then "w" will be the second argument.
So that does all work. And here is that code.
So now we have the operator plus outside the class.
I have made the operator a friend, here.
If you like, you can try making it a member function and having this one delegating to it.
And then the main() function is the same as before.
So let's see if this works.
And there we are.
So now we can add "hello" and "world" to get "hello world".
So when should you use member and non-member operators? If you have an operator which changes the state
of the object, that should be implemented as a member function.
So things like plus equals, compound assignments. And also increment and decrement operators.
If you have an operator which is closely bound to the type of a member. So something like the dereference
operator, which will return an object of the same type as the member.
There are some operators which can only be defined as member functions.
So that is the assignment operator. The subscript operator.
So this will take an argument which is an integer, and it will return some element within your object.
The mysterious function call operator again. And the arrow operator, crow's foot, whatever you want to call it.
These have to be member functions.
If you have a binary operator, which might require a type conversion, then you should implement that
as a non-member function.
So we saw that with the plus operator.
And that applies to all arithmetic operators.
Also the equality and relational operators. And the bitwise operators.
And that includes the bitwise operators which we use for input and output.
So, that is, left shift and right shift.
These should be non-member functions, so they are compatible with all the built-in types and the library
types.
Okay, so that is it for this video.
I will see you next time, but until then, keep coding!