WEBVTT

00:02.360 --> 00:09.530
Hello again! In this video, we are going to look at namespaces. Namespaces are another tool for helping

00:09.530 --> 00:11.000
us organize our code.

00:11.510 --> 00:14.900
If you think about that, we already know quite a few ways to do that.

00:15.380 --> 00:19.750
We can divide our code into separate files. Within a file,

00:19.780 --> 00:22.370
we can divide the code into separate functions.

00:22.850 --> 00:26.540
We can organize our data by putting it into structs or classes.

00:27.800 --> 00:31.620
We can also put the code that manages that data into the class.

00:32.750 --> 00:39.260
We can manage object files by creating binary libraries, DLLs or shared objects.

00:40.130 --> 00:45.890
And we can use namespaces for grouping together symbol names, which are logically related.

00:46.700 --> 00:52.460
So typically you do this if you are writing a library. You would create a namespace for your library and

00:52.460 --> 00:55.520
then all your symbols would be defined within that namespace.

00:57.140 --> 01:02.510
One example that we all know and love is the C++ standard library.

01:02.870 --> 01:06.290
This defines the std, standard, STD,

01:06.950 --> 01:09.710
however you pronounce it, namespace.

01:09.710 --> 01:16.370
And this namespace contains the names of all the functions, types and variables that are defined by the

01:16.370 --> 01:17.990
C++ standard library.

01:21.060 --> 01:28.950
Why is this useful? If you are writing a large program like you do in paid-for programming as opposed

01:28.950 --> 01:35.280
to educational programming, you often use several libraries, and it is quite possible that different

01:35.280 --> 01:38.370
libraries decide to use the same name for different symbols.

01:39.120 --> 01:43.260
So you could have two different libraries, which both have a class called Test, to use

01:43.260 --> 01:50.400
our favourite class name. C++ has a "one definition rule" which says that a symbol can only be defined

01:50.400 --> 01:53.640
once, even if you want it to have different meanings.

01:55.230 --> 02:00.120
If we have two different libraries which both have a class called Test, then that is not one definition, that is

02:00.120 --> 02:00.940
two definitions.

02:00.960 --> 02:02.460
So the code will not compile.

02:04.390 --> 02:07.570
One solution, and if you're working in C, it is the only solution.

02:08.260 --> 02:10.840
Obviously, you can't have classes and sea, but you can have structs.

02:11.140 --> 02:13.420
And also, they need to do this to overload functions.

02:14.110 --> 02:19.900
So what you do is to add a prefix to the name which is specific to that library.

02:20.410 --> 02:26.820
So if we work for the Alpha Beta Corporation, we could put abc underscore in front of all our class and

02:26.830 --> 02:35.560
function names, and someone else could put a different prefix for the names. Which is all rather

02:35.560 --> 02:36.190
laborious.

02:38.360 --> 02:42.860
In C++, there is a much better solution, which is to use namespaces.

02:45.900 --> 02:52.200
So we create a namespace for our libraries, so we put namespace and then abc, which is the name of the

02:52.200 --> 02:52.770
namespace.

02:53.250 --> 02:59.520
And then inside the curly brackets, we put all the symbols that we want to declare as being in this

02:59.520 --> 03:00.180
name space.

03:04.060 --> 03:10.600
So every symbol that goes in there is going to be inside this namespace, and the compiler will automatically

03:10.600 --> 03:12.790
put the name of the namespace in front of it.

03:13.210 --> 03:15.400
So we have our class Test in the namespace.

03:15.400 --> 03:22.150
abc. And the compiler will regard this symbol as being abc double colon Test.

03:22.900 --> 03:24.760
This double colon is the scope operator.

03:25.130 --> 03:31.390
You've probably seen it before for member functions, for classes. So that means the member function belongs

03:31.390 --> 03:31.990
to the class.

03:32.290 --> 03:36.100
And this means that the Test symbol belongs to the abc namespace.

03:40.620 --> 03:45.870
And then if we want to refer to this symbol when we're not actually in the same space, we need to

03:45.870 --> 03:48.740
put the namespace name followed by double colon.

03:48.810 --> 03:56.070
So if we want to create a Test object, we put abc double colon Test, and then we can create the object.

03:56.550 --> 03:59.970
So that'll create an object of the test class from the namespace.

04:00.000 --> 04:00.750
abc.

04:05.540 --> 04:11.930
If we have a name which does not belong inside any namespace, it is said to be in the "global" namespace.

04:12.950 --> 04:15.410
This global namespace has no name.

04:15.410 --> 04:24.290
So if we just use a symbol without any qualifier or if we just use an empty scope operator, that will

04:24.290 --> 04:25.820
refer to the global namespace.

04:29.570 --> 04:37.100
If we define a Test class which is not inside a namespace, that will go into the global namespace and

04:37.100 --> 04:38.330
then we can just put "Test"

04:39.910 --> 04:44.980
to get an object or put dobule colon if we want to be specific, that we are referring to the global

04:45.040 --> 04:45.700
namespace.

04:50.710 --> 04:56.820
You are allowed to split namespaces across different parts of the code. So you can start writing a namespace

04:56.820 --> 05:01.170
in one part of the code and break off and then come back later on.

05:01.800 --> 05:08.970
You can even spread it across different files. So you could have a namespace in a header. And then in

05:08.970 --> 05:10.950
a source code file, which includes the header,

05:11.310 --> 05:16.860
you can continue with the namespace, so you could have a class definition which has the members and

05:16.860 --> 05:19.500
the signatures of the member functions.

05:19.980 --> 05:27.690
And then in the C++ source file, you can actually put the function bodies and define the member functions.

05:36.000 --> 05:40.800
What happens if you have a symbol that is defined in two different name spaces?

05:42.210 --> 05:48.120
If there's some sort of hierarchical relationship between them, because namespaces have a hierarchy.

05:48.270 --> 05:51.800
You can actually define namespaces within other namespaces.

05:51.800 --> 05:59.490
So you could put a namespace inside abc. And all namespaces are assumed to be inside the global namespace.

06:00.000 --> 06:05.040
So the global namespace, if you like, it outranks all the namespaces which have names.

06:07.970 --> 06:16.250
If we define x as a symbol in the global namespace and then have another symbol x inside a namespace

06:16.250 --> 06:23.660
abc. If we refer to this x inside the abc namespace, it will refer to its own one.

06:23.960 --> 06:28.250
So this x here will refer to the abc version of x.

06:29.600 --> 06:35.510
We can use the global scope operator, the double colon, and that will give us the global version of

06:35.510 --> 06:35.900
x.

06:38.930 --> 06:45.200
So here is some codes to demonstrate that. We have our variable x in the global namespace.

06:45.650 --> 06:49.100
There is a "using namespace std", which I will talk about in a minute.

06:50.240 --> 06:52.090
We have an abc namespace.

06:52.430 --> 06:55.790
We are defining another variable x, which is inside this namespace.

06:56.540 --> 07:01.460
So this is going to be abc colon colon x, and this is just going to be colon colon x.

07:02.480 --> 07:09.290
We have also defined a function inside this namespace, and this is going to printout the two x's.

07:10.010 --> 07:15.020
So the first x is going to refer to the namespace in abc. And the second x,

07:15.410 --> 07:18.410
This specifies that we wants the one from the global namespace.

07:20.030 --> 07:24.080
And then in the main function, we are calling this function. It is in the abc namespace,

07:24.110 --> 07:26.570
so we put abc colon colon in front of it.

07:27.740 --> 07:33.710
If we miss that out, the compiler will try to find a function in the global namespace called func,

07:33.710 --> 07:36.500
which takes no arguments. And it will not find one.

07:36.830 --> 07:39.990
So we get an error. There we are, identifier

07:40.040 --> 07:40.610
not found.

07:42.660 --> 07:43.530
(So, put that back)

07:45.950 --> 07:50.630
And then when we call this function, it will be in the abc namespace and - well, we have been through

07:50.720 --> 07:51.120
all that.

07:51.890 --> 07:54.890
So let's see if we get the results we expect. And yes, we do.

07:55.190 --> 08:04.100
So x is going to be the x in the abc namespace, value 47, and double colon x is the one from the global namespace with

08:04.100 --> 08:05.300
value twenty three.

08:10.920 --> 08:12.390
And in fact, we could also do...

08:20.530 --> 08:25.060
Just as another example of accessing a variable outside its namespace.

08:25.510 --> 08:27.580
So that's the abc version of x again.

08:29.500 --> 08:35.050
And if we just change that to x, then we will get the global version again.

08:35.470 --> 08:36.040
Twenty three.

08:36.580 --> 08:36.780
Yes.

08:36.940 --> 08:37.210
Good.

08:38.990 --> 08:41.810
There is something called a "using" declaration.

08:42.380 --> 08:47.960
So this will bring a namespace from a lower level namespace into a higher level one.

08:48.260 --> 08:55.230
So for example, we could do this to bring the test class from the xyx namespace into the global namespace.

08:55.640 --> 08:59.570
If we do this outside any namespace definition.

09:00.800 --> 09:04.010
So using xyz colon colon test.

09:04.430 --> 09:08.720
So we are now creating an alias for this name.

09:09.050 --> 09:14.720
So every time we put "Test", the compiler is going to assume that this refers to the xyz version

09:14.720 --> 09:15.230
of Test.

09:16.900 --> 09:22.930
We can still do abc colon colon Test to get the alpha version, and if we want to specifically get the

09:22.930 --> 09:25.330
xyz, we can do xyz colon colon test.

09:26.110 --> 09:32.260
If we need the actual global version, then we have to do colon colon to get the one from the global

09:32.380 --> 09:32.980
namespace.

09:35.560 --> 09:41.680
And then, once we write a using declaration, this will take effect until the end of the enclosing scope.

09:42.070 --> 09:47.770
Or if you do it at the global scope, then it is going to be in effect until the end of the file.

09:52.720 --> 09:58.000
And in fact, you can use the "using" directive to bring in an entire namespace.

09:58.600 --> 10:01.060
So if you put using namespace std.

10:01.660 --> 10:07.270
That will bring every single symbol from the C++ standard library into the global namespace.

10:08.770 --> 10:15.820
So instead of having to put std colon colon and cout we can just put cout. And we can do that.

10:16.240 --> 10:19.480
Now, you have probably noticed that I have been doing that throughout the course.

10:20.230 --> 10:25.420
And you may know that this is not regarded as good practice, and I would actually agree with that,

10:25.870 --> 10:28.600
because this "using namespace" defeats

10:28.600 --> 10:32.570
the point of having namespaces in the first point. Someone has gone to the trouble of creating

10:32.570 --> 10:37.540
a namespace and putting all their symbols in it, and then you go and put them back into the global namespace

10:37.540 --> 10:37.810
again!

10:37.870 --> 10:47.560
So it is all counterproductive. And I would not do this in "real" code for work, but for educational

10:47.830 --> 10:49.180
training examples,

10:49.570 --> 10:50.770
I think it does have value.

10:51.910 --> 10:55.750
The whole point of having an example is to provide the simplest possible example.

10:56.170 --> 11:01.240
And if you have std colon colon for doing something like an iterator to a vector of string, then

11:01.240 --> 11:06.220
you are just going to have an explosion of [colons] and namespace qualifiers. It is quite hard to make

11:06.220 --> 11:07.330
out what the actual code is.

11:08.440 --> 11:10.090
So, that's my excuse anyway!

11:10.960 --> 11:14.380
And I think that is actually quite a common approach amongst instructors.

11:15.220 --> 11:23.290
But because I do it in here, in examples, do not necessarily do it in your workplace. Or if you are a student

11:23.290 --> 11:30.190
and you go out into the big wide world and some says you must not use "using namespace", then they are right

11:30.310 --> 11:32.200
or in my opinion, they are right anyway.

11:32.990 --> 11:33.280
OK.

11:33.850 --> 11:36.280
Sorry, I am rambling a bit! I had better stop there!

11:37.060 --> 11:39.700
So that's it for this video, and I'll see you next time.

11:40.060 --> 11:42.070
But until then, keep coding!
