So last lesson kind of ended abruptly, but I'm going to continue on kind of where we left off.
We're going to talk about a couple of new subjects today, but I'm not really going to have a slideshow
associated with that.
I'm just going to kind of go straight into the code.
So we left off talking about using a pointer to a struct object and kind of how it changed things in
our loop, right?
So it changed the output that we saw because when we modified the pointer, it modified that same memory
and we were actually just storing pointers in the vector that we're all point the same memory.
So it kept getting changed.
And so the pretty much everything in the vector.
Ended up just being like a another plant of the same memory and the last thing that was in that file
right here, person input that.
Was in fact, you know, it was everything was Nancy, like, for example, you.
So what if we just want to not have it do that and not change it, but we still want to use dynamic
memory, and that's why we're going over right now.
So what am I doing off the bat is I'm going to get rid of these because I'm actually going to use variables
now like we were before.
So what I'm going to do, I'm actually going to get rid of this as well.
Copy it.
But what I'm going to do is say, I'm going to say string name and age like we were before and then
wait.
And then what we're going to do is we're going to read into these variables and then I am going to make
a new person object and then I'm going to set them here.
So I'm going to say Parrow name equals name P Arrow age, eagle's age and P arrow weight equals weight.
So now what happens is I read everything in first from the file into variables.
Then I make a new person object each time.
So this is.
Actually going to be not the same person.
It's actually going to be a new dynamically allocated person before we had it up here, and we were
essentially just using the same person each time.
And so we're pointing to the same memory.
But now what we're doing is we're making we're explicitly making a new piece of memory on the heap for
our person and then we're making a pointer to that on the heap.
So each time it's going to be a new pointer to a new area of memory Hempstead of the same variable name.
But it's actually going to be a new chunk of memory each time, rather than just sharing the same chunk
of memory like before.
Then we set all these to the appropriate variables.
The reason I did this is just so it was kind of clean to be able to read into the variables here, make
a new object and then set them rather than read them straight into these data members.
And then what we can do down here is just push it back to the vector edge because our present fact is
of type person pointer.
So we're going to say person vector pushed back and put P there.
So now let's see what happens, so I still left these like arrows down here.
But now we're making a new object each time and adding that to the vector, we're adding the pointer
to the new object each time to the vector.
So let's go ahead and save this.
I will do it, C++.
This is just a copy.
Hmm.
All right.
So let's go ahead and run it with
five easy person input.
All right.
So now let's go ahead and scroll up, and we noticed that we see three different people now, so we
have Bob, Jeff and Nancy.
So in this order here.
And if I switch this back to how it was before.
I say this will go ahead and run this again, and you notice now Jeff is at the end, so we have different
people now because what we are doing is we are actually creating a new person each time in a separate
region of memory.
Right now, new keep allocated person struct and then we're making a pointer to that each time to that
new area.
So each person has their own area of memory, and we're adding the pointer to each one of those areas
of memory to the person that each time.
So if we wanted it dynamically allocated and we didn't want to change the same region of memory, we
would just need to put this inside of the well.
And of course, you notice I changed.
I added this kind of changed this over reading into variables so I could accommodate for this new style
of code in here.
All right.
So with that, I'm going to go kind of into something else.
I want us to look over another subject and another practice problem.
And so what we're going to do for this is talk about how structs can.
Actually, not only have primitive data types in them, but they can also have like another struct,
so you can have some other name in here like, let's say it was person and like dog or something, you
know, dog like a person's dog, something like that.
Like, we had some structure called dog.
You don't have to be limited to only having, you know, strings and ensign floats and doubles and all
these other things that you've learned thus far.
As the data types of your struct, you can have other structures, as members write, like I said with
the dog.
I'm actually going to demo a quick program I wrote here.
And what we're going to do is instead of me writing the code in front of you, I'm actually just going
to go through this code.
We're going to go through it together.
It's already written and we're going to comment some stuff and kind of talk about what's going on there.
So let's go ahead and run this.
You see that I have compiled an executable called S2 for ICSI.
So if I run this, it says, enter known buildings.
I'm going to say to into the number of employees for building zero.
I'll say to Inter employee select employees your name.
I just say Jeff Programmer number of employees for building one.
I will go ahead and say to employees for this, and I'll just say, we'll say Jessica, and then maybe
just like a manager or something like that, another name.
Bob, how about Janet or something like that?
OK, and then what it does is it prints out the employees for each building, right?
So.
We have employee list for building zero, it was only Jeffrey Shipload, programmer and the only person
in that building kind of said then we have employee list for building number one.
And this has desk and manager and bob janitor and some IDs there.
So it's associating employees with buildings, and it's also keeping track of buildings as well.
So let's just keep that in mind.
We know how the program functions as far as running it.
So let's take a look at the code here.
So I've obviously included I don't really need I am have been here.
This is something yeah, I'll leave it for now, but I don't think I actually use it.
We have a vector and I stream in here because we're using vectors and we're of course, having output.
So first off, let's take a look at this structure right here.
So we have this struct employee, right?
The employee has an ID and name a job title.
So let's go down a little bit now.
We have another struct right here.
This struct is called building.
It has a building number, which is an integer and has no employees or assistant, which is an integer.
And then here it has a vector.
So this isn't this is something we haven't seen as part of a struct yet, but you can have a vector
inside of a strict and this vector is of type employee pointers.
So it is one of our abstract data types, right?
Employee right here.
So each building that we create will have its own vector of employees.
And actually, it's not going to be a vector of the employee structure.
It's actually going to be employee pointers, right?
So we have this employee's variable right here that we will use for that vector of employee pointers.
So it was kind of connecting it's important to connect like these abstract data types to one another.
This is something that we would call a composition.
So employee, basically a building has employees, but employees do not have buildings, right?
That's the relationship.
So this building contains multiple employees.
That's why we have a vector of employee pointers in here.
So something new, you don't have to only have primitive data types and some of the other data types
you've seen so far, like string.
You can also have your own data types, so this doesn't have to be a vector of employees, it can also
honestly, just let's say the building had like just one manager or something like that.
So you could also say employee, employee manager, something like that, you know?
So now there is a variable in here that is of type employee and it is the manager, so you can have
that as well.
So let's go ahead and look at the rest of the code, how do we set this up?
So let's go ahead and comment some stuff to you.
So this is,
let's just say, elite for employing use.
This will be our and 80s forces for abstract data type affected time for buildings.
So right here we declare no buildings, and we're doing that because we're going to get the number of
buildings from the user, if you remember here.
We said internet buildings, right?
And that's what we see right here, internet buildings, and then we read in the number of buildings.
We also make a vector that is super annoying and that comes up.
We also make a vector here.
Of building plaintiffs.
So let's go ahead and comment this, so I'm just going to say actually right here, so we'll say when
you say container building meters.
So you can think of it as a container of buildings.
Right, because I mean, even though they're there pointers, we're going to be making new buildings
for each like point.
That's going to point to a new building in memory, right?
Because we're going to be doing this down here.
So container building pointers and then right here, we're going to get the number of buildings from
the user.
All right.
And then right here we start looping.
So what are we doing in this loop where we're looping as long as I as less than number of buildings?
So no buildings?
So what we're going to do in this outer loop that I've declared here we are going to use that to create
as many buildings as the user said, right?
The users specified how many buildings we should have.
So we're going to loop for as many times as the number of buildings is.
And so what we do right off the bat is we're going to create a building right for each one of those
buildings that the number specified, the amount of buildings is well, I mean, we're going to make
a new building right now, actually put the comment over here.
So we'll just say great new building.
And I'll just say dynamic, right?
Because we're making like a dynamically allocated building.
Let's do that.
All right, so now we have some more of this syntax with the little arrow.
So what we are doing is since we've made a new building and it's a pointer to dynamically allocated
building, we now want to set the building number.
And all I'm really doing here is I'm setting the building number to I.
So if the user says, you know, I'll I want, you know.
Two buildings.
Then the first building will be building zero, right, so I said I will be zero and I'll set the building
number two, I and then when I make the next building, how said the building number two again, but
it will be one as it would move four, zero and one if we had two buildings, right?
So this is like set the building, no.
Then we enter the number of employees for the building, we're going to get that from the user, right?
So we're going to ask them.
All right.
Each building has a vector of employee pointers, right?
So.
We want the user to now say how many employees are going to be in this specific building that we're
on in this loop iteration, right?
So we say in a number of ways for building AI, which is just a building number, right?
And then we read it in with CNN and we're using this pointer syntax again.
So we're doing B Arrow.
No employees were reading it directly into this, no employee's variable.
So where is that we have right here in our building structure says aren't enough employees.
We are accessing this variable in the struct by doing our variable name right.
B is the pointer to the new building that we made and we're doing b arrow instead of a dot, right?
Because it's a pointer, so it's an arrow.
Be era and have employees, so we're reading directly into that variable right here with see it.
So read into no employees variable.
All right.
So now what, we're in this outer loop we read in the now employees will now what we have to do is to
deal with all the employees for this building, right?
The user specified the number of buildings.
So we're looking for that number of buildings with this outer loop.
Now the user has specified inside of this with the number of employees for this building.
So now we have to initiate a nested loop that's inside of here that loops for the amount of employees
that the user entered.
And I'm using the variable j for that.
So what am I doing right here?
Well, I'm just straight up using be employees, right?
Because we read that we read straight into that struct variable.
And so what I want to do is I want to loop based on that.
So I'm going to loop as long as chains less than be Arrow.
No employees.
So just like we created the building pointer, we're going to create an employee point array and dynamically
allocate a new piece of memory with an employee struct.
So great new employee dynamic
allocation.
OK, so here we set the employee ID is kind of similar to the building, no I.D. So set your employee
I.D..
All right, so now what we do is we're going to read into the employee's name because we asked the user,
say employee, and this is employee ID basically right j is the same thing as it.
So they say employee j name and then the user's going to enter the name.
So this is the employee's name.
Employees at the.
And then here in the job title, right, so we're doing the same thing, it's just like that with the
B in the arrow right now we're doing E Arrow ID, so that's accessing this variable.
And then we're doing, you know, name and job title, and these are these other ones right here that
we're accessing, right?
And remember, the E!
Is the variable name that we have, for instance, of the we have one instance of this church created
here, and that's happening each time that we look.
This is dynamically allocated instance of district.
Called E!
And so that's why you see the Arrow I.D..
So we're making new employees each time that's based off that strict setting, the information for the
employees to set an employee's job title.
And then we push it back to the vector, so we have our employee vector, so this is kind of interesting
here, so.
B is the building that we're currently on, right, so right here.
This is the outer loop, right?
So we're on this building B was created, we now initiated a loop inside this loop.
So we're we're still referring to this building, right?
But now we're creating the all the employees for this building.
So.
Each time we create a new employee, we now need to we've set all the information here for the employee.
Now we need to say, OK, let's refer to the building we're on.
It's this right here, right, because we're on this outer loop iteration.
So the current building, let's get the employee's vector, right?
So we're able to refer to the employees vector by doing an arrow since it's a pointer, right?
It's a pointer.
We want to access this variable right here, employees, employees, so we're doing the arrow employees
that gives us this vector.
All right.
Then what we have to do, or sorry, that Vector is not a pointer.
The building is a pointer and the employee is a pointer, but that vector in the building structure
is not a pointer, so we're going to use the dot.
Again, we do it.
We refer to we use the arrow when it's a pointer, but if it's not a pointer, we're going to use a
dart, right?
So we're going to employees dot pushback.
This is just the standard method for the vector right dot push back.
You've used that before.
What are we pushing back or pushing back the employee pointer, right?
This guy right here, we've already said all the data, so it's set up and we're ready to push it back.
And why does that work if it's a pointer, how do we push it back?
Because the data type is employee pointer, that's the data type of vector that's in each building.
All right, so the prints out in line and now right here, since we have set up all the employees for
the building and we've also set the information for the building.
We are now ready to push back the building pointer, this building pointer that has all this stuff associated
with it now.
All the employees have been pushed back to the vector in their.
We're now going to push the building back to the building vector, right, this building pointer type,
the vector of type building pointer called buildings.
And you notice here we push back the building to it.
So we have a vector for each building and then we have an overall vector that holds all the buildings
right.
The vector for each building holds all the employees.
The vector with all the buildings is something that was created locally here in Maine, and it holds
all the buildings there.
OK, so that will create all of our buildings with all the employees in each building, with all the
data for each employee.
Now here is where we start to loop over and print it out, so.
I'm just going to write a couple more notes here that we didn't write, yes, I'm going to say push
back
new employee to.
Let's just say it more in abstract terms, so a sign employee to building to buildings, the employee
that must do that and say the typing is yes, it's still struggle for me.
So.
So buildings don't push back.
This is just
adding the completed building to building effect.
How about that?
So now here comes the time to print out all employees for each building.
So that's what we're doing, we have a nested loop and why do we have in the loop?
Because we're basically having to go over each building and for.
So I say.
For each building.
We have to go for each employee in the building, right?
So that's what this interlude is for, it's for all the employees of the current building that we're
on, this is for each building.
This loop is for each employee of that building.
Of each one of those buildings.
So interesting looking syntax here, let's go ahead and look through it, so it says see our employee
list for building number.
And what do we do?
Well, we're looping over buildings that size buildings is the vector that was created locally here,
right?
Right here, the local building inspector.
So we're going as long as ISIS and building societies that will print out each building and give us
access to each building.
So what we are doing is we are using AI to index the buildings vector.
So this highlighted thing right here is going to resolve to a building pointer.
Right.
Because what type is that vector that's local to main that says buildings?
It's type building pointer.
So this highlighted thing right here.
When we index that vector, it will give us a building pointer, and that is why we now need to use
an arrow to access the building.
No variable of that building pointer, right?
So that building pointer has a building number right.
We have a building number for each building.
We know that we making building pointers here.
So this building pointer is going to have this building no variable and we are accessing it through
an arrow once we have it right and we're going to print that out.
Similar thing is going on with the rest of this, right, we're just using arrows to resolve each one
of the layers of data here, so.
This inside loop loops for the what is the current building we're on, and that's what we're asking
right here.
Current building and that's a building pointer, so we use an arrow.
Now we're getting the vector of employees out of the building, right?
We know that that has each building has a vector of employee pointers.
So this is the vector of employees that we access, and then we say, since the vector itself is not
a pointer like we're not have any pointer to the vector, we're just going to use the dot right, just
like we did Dot push back here.
We're going to need size.
So.
Let's kind of recap again.
Let's get the current building we're on, right, because we're looping over the buildings in this outer
loop.
Once we have that building that we're currently on here, we say, OK, let's get the vector from that
building.
And how big is that vector?
Let's make sure that we loop as long as just less than.
The size of this vector for the current building.
So that's just looping over for all of the given employees in one vector, you know, because this enables
us to have different sizes, of course.
For the buildings like we did in our example, you know, one of the buildings only had one employee,
but another building had two employees.
So that's why we want to refer to the specific size of that building's employee, Victor.
Then in here, we print out all the stuff for each employee and how do we do that?
It's kind of redundant.
I have this set with here, but I don't really need to use it.
So you can kind of ignore that I'm not really using that correctly here.
I'm just having this over.
So I'm actually going to get rid of these right here.
So.
Let's go ahead and get rid of that.
OK.
So I just have some stuff tabbed over, like, for example, here is says See Out tab.
This is a tab.
And then we say I'd.
We do a space and then what are we going to do?
Well, we're going to access the current buildings employee vector.
And that's right here.
Current building is what I have highlighted here.
Then what is this?
It's a pointer, so we're going to access the Good Lord.
OK, we're going to access the employee vector of that current building and that is going to be what
we're going to do is not only access that vector right here, but we are going to index the employee
vector.
I'm just hoping that I can not have so much stuff pop up when I'm trying to show you.
But so what are we doing, we're accessing the employee vector of the building, right?
So we have this employee vector, but this time we're not only just accessing the vector, we're indexing
that vector and what's stored inside of it.
Employee pointers.
All right.
So.
Get the building pointer.
Use the arrow.
Get the employee vector.
Get an employee out of that vector with the index operator there.
Use the arrow since the employee is a pointer to employee pointer.
Get the idea from that employee, right?
So the employee has the ID.
So just trying to break down this whole thing for you and I'm just not going to hover over it too much
more because it's just bringing up so much kind of information about each thing that I have here.
So that's kind of annoying for this purpose.
So we have each time that we print something out, I can just kind of go down here and go over it.
So we're getting a building out of the building inspector that's going to be a pointer, a building
pointer.
So we use the arrow that with that, we go to access that specific building's employees vector.
We're also going to index that employees vector to get the current JS employee right because we're looping
over the employees for that building.
Once we get that employee out, it's an employee pointer because we have been making the employees dynamically
with a pointer and putting that pushing that back to this employee's vector, right?
Once we have that employee pointer, we can get information about the employee like I.D. name, job
title, right?
And what are those again, just to once again recap on that, they're coming from here because we defined
our strike to have those variables right?
So this is us printing out all that data about the employees, right?
OK, so that is pretty much all I'm going to go over in this.
Listen, I just wanted to show you that you can have strokes inside of strokes.
This was not just a struct variable inside of another struct, it was a vector of the other type of
struct.
Right.
And not only that, it was struct pointers in here.
So it's kind of it kind of goes with the overall design of your code.
So we're thinking about an abstract idea and trying to come up with an abstract data type.
We need to think, well, you know, what is the relationship between employees and buildings?
How should I turn this into code?
Well, each building has, you know, a bunch of employees.
Could I make a list of all those employees?
OK, I probably could.
What is a good thing to use for a list?
Well, either an array or a vector.
This is kind of just coming up with the idea for the code, you know?
OK, so I can make a building struct right for an abstract data type.
Let's have the information associated with it for each building.
And since each building is going to have a list of employees, I should make in a vector of type employee.
Right.
So I have this variable there and it says vector employees.
I'm also going to need an abstract data type to represent an employee, right?
An employee has an idea, a name and a job title.
So that's how you can kind of relate these to strikes in that way.
OK, so we're going to be moving on from structs.
I think you now know enough to use them as as abstract data types.
You know that you can use them in an array in a vector, you can put them in there, have arrays of
strikes and vectors and strikes.
You know that you can have multiple strikes and they can be related in a way like this with like the
composition way where you know, a building has employees.
We also could say that a building has an employee, one employee that's a manager as well.
You know, I didn't put that in here, but like I was talking about in the beginning, that is possible
as well.
You could say that a building has a single employee manager as well.
And so what we're going to be moving on to is something that is kind of a new with a new paradigm in
programming.
We've been doing procedural programming up until now, right?
Remember one of those lectures?
I talked about the fact that we had been doing procedural programming and that we at some point we kind
of added on to our procedural programming.
Was kind of this modular programming where we were using more functions and stuff.
I haven't been breaking everything into functions.
It would be really good if you could break this into some functions.
I'm hoping that you're using multiple functions in your program to organize things better.
We're going to move on past that procedural programming thing now.
And we've talked about stress.
We talked about abstract data types.
Strokes can still be part of that procedural programming or functional programming or modular programming
because strokes were available with the C language before C++.
But C++ kind of brought about the ability to do it, didn't bring it about, but I'm just saying that
C++ has the ability to do something called object oriented programming.
OK?
Structures are kind of bringing us into the realm of objects and object oriented programming.
You could think of this struct as an object.
It's an abstract data type.
We're going to continue on with the idea of abstract data types and trying to bring abstract ideas into
code and represent them.
You know, here we're representing something that's not in numbers.
You know, it's an employee and employee is not something that's just baked into coding languages.
You know, you have to come up with your own kind of structured data for this.
So you say, OK, I'm going to associate some data with an employee, right when you use the name employee.
And I'm going to associate the fact that employee has an Indian name and a job title to create this
abstract data type in the code.
Same thing with the building.
What we're going to do is move on to something called object on your programming, where we're not going
to use structures anymore.
It's going to be very similar to structure, almost identical, but they're going to be called objects,
and we're going to need to introduce this whole new idea of something called a class to be able to do
that.
So to take everything you know about structs and remember it because we're going to be continuing on
with this idea of abstract data types, but we're going to be using a new thing besides a struct, and
it's going to be called a class.
So with that, I will see you in the next video or we will get started with object oriented programming.