WEBVTT

00:00.120 --> 00:07.020
Hello again! In this video, we are going to look at member and non-member operators. When we are writing

00:07.020 --> 00:08.250
an overloaded operator.

00:08.490 --> 00:13.290
We can usually implement it either way: as a member function or a non-member function.

00:14.910 --> 00:17.490
If you can, you should implement it as a member function.

00:18.000 --> 00:23.460
This will provide direct access to the private data. It is a member function, so we do not need any friends

00:23.460 --> 00:26.160
or delegate member functions.

00:26.760 --> 00:31.860
And also, it keeps all the code that is related to the class together, in the class definition.

00:34.680 --> 00:40.980
There are some operators which work better as non-member functions. And there are a few which cannot be implemented

00:40.980 --> 00:42.180
as member functions at all.

00:46.540 --> 00:52.060
The problem with having operators as member functions arises with binary operators. If we

00:52.060 --> 00:56.050
want a type conversion - actually, let's look at this in the IDE.

00:58.090 --> 00:59.860
So here is our String class again,

00:59.860 --> 01:06.460
with a capital 'S'. We have briefly gone back to using the library string as the member, to keep things simple.

01:07.420 --> 01:12.220
I have added a constructor which takes a C-style string, because we are going to use one of those.

01:13.780 --> 01:16.960
We have a plus operator as a member function.

01:17.380 --> 01:24.320
This will take another object of the same class. And it will add the library string member to our own library string

01:24.340 --> 01:26.080
member, and return the result.

01:27.100 --> 01:30.760
We have the member function for printing out the member.

01:32.610 --> 01:39.540
And in our main() function, we create a couple of objects of this class. And then we try out our new operator.

01:40.440 --> 01:43.830
So if both the arguments are objects of our class, it works fine.

01:44.610 --> 01:51.950
This is actually called as a member function call. So this will call the member function on "w", operator plus, with

01:51.950 --> 01:53.040
"bang" as the argument.

01:54.570 --> 01:59.070
So this will add the library string inside "w" to the library string inside "bang".

02:01.330 --> 02:07.570
And that all works. If we have a string object with data "world" and one with an exclamation mark, then we get

02:08.200 --> 02:09.430
"world", exclamation mark.

02:14.300 --> 02:21.170
The problem arises is if we want to use a string conversion. We have a constructor which can convert

02:21.620 --> 02:24.800
 C-style string into one of our Strings with a capital 'S'.

02:26.750 --> 02:32.930
The problem is, we only have a member function. And you cannot call a member function on a C-style string.

02:33.890 --> 02:35.920
So this is going to give a compiler error.

02:38.810 --> 02:46.190
There we are. No global operator found. So the compiler could not work out how to call this member function

02:46.190 --> 02:52.390
from the C-style string, and it looked for a non-member operator plus. But, because we implemented

02:52.400 --> 02:56.900
the operator as a member function, there is no suitable non-member function.

02:57.950 --> 02:59.330
So that is the problem that can arise.

03:04.000 --> 03:10.000
If we use a non-member function, so the operator plus is defined outside the class, then it all works.

03:11.440 --> 03:17.470
The call to the plus operator is the call to a non-member function, with arguments "w" and "bang", and the

03:17.470 --> 03:20.920
compiler will convert function arguments if it can.

03:21.370 --> 03:27.790
So in this case, it is going to convert the C-style string "Hello" to a String with a capital 'S', by

03:27.790 --> 03:31.720
calling that constructor, and then "w" will be the second argument.

03:34.470 --> 03:38.730
So that does all work. And here is that code.

03:39.060 --> 03:42.020
So now we have the operator plus outside the class.

03:43.390 --> 03:46.440
I have made the operator a friend, here.

03:47.970 --> 03:52.260
If you like, you can try making it a member function and having this one delegating to it.

03:54.160 --> 03:56.800
And then the main() function is the same as before.

03:57.310 --> 03:58.390
So let's see if this works.

04:00.190 --> 04:00.700
And there we are.

04:01.060 --> 04:04.510
So now we can add "hello" and "world" to get "hello world".

04:07.020 --> 04:13.440
So when should you use member and non-member operators? If you have an operator which changes the state

04:13.440 --> 04:16.650
of the object, that should be implemented as a member function.

04:17.190 --> 04:23.490
So things like plus equals, compound assignments. And also increment and decrement operators.

04:25.440 --> 04:31.170
If you have an operator which is closely bound to the type of a member. So something like the dereference

04:31.200 --> 04:35.580
operator, which will return an object of the same type as the member.

04:39.760 --> 04:43.160
There are some operators which can only be defined as member functions.

04:43.180 --> 04:46.870
So that is the assignment operator. The subscript operator.

04:47.350 --> 04:54.130
So this will take an argument which is an integer, and it will return some element within your object.

04:55.210 --> 05:02.320
The mysterious function call operator again. And the arrow operator, crow's foot, whatever you want to call it.

05:03.160 --> 05:04.600
These have to be member functions.

05:07.850 --> 05:13.280
If you have a binary operator, which might require a type conversion, then you should implement that

05:13.280 --> 05:14.540
as a non-member function.

05:14.900 --> 05:16.700
So we saw that with the plus operator.

05:17.120 --> 05:19.130
And that applies to all arithmetic operators.

05:20.000 --> 05:25.640
Also the equality and relational operators. And the bitwise operators.

05:27.470 --> 05:31.630
And that includes the bitwise operators which we use for input and output.

05:31.640 --> 05:33.260
So, that is, left shift and right shift.

05:34.190 --> 05:39.110
These should be non-member functions, so they are compatible with all the built-in types and the library

05:39.110 --> 05:39.530
types.

05:41.300 --> 05:43.130
Okay, so that is it for this video.

05:43.580 --> 05:46.670
I will see you next time, but until then, keep coding!
