- [Instructor] C++ classes can have member functions
that act as methods for the class.
Here's a working copy of class.cpp from chapter six
of the exercise files.
We have this very simple class, we've seen it before,
we have one data member and it's a private data member,
which is the default by design,
so that our data is encapsulated.
And we have the public section
with two public function members,
which are used for setting and getting the value.
And down here, we declare an object,
we set the value, we get the value,
and when we build and run, we get our result.
It's also considered best practice to separate
the interface from the implementation,
and this is done by declaring the member functions
in the class, and defining them elsewhere.
So we can change this to a declaration by simply
replacing the code block with a semicolon.
And then we can define these functions elsewhere,
usually in a separate file.
And so here, I can say: void C1, set value.
And you notice I use the C1 with two colons
and this tells the compiler this set value is the definition
for the member function for the class called C1.
And I say int value, and give it its code block now.
And I can do the same for get value.
And now when we build and run,
we get exactly the same result, and in fact,
the compiler is generating exactly the same code.
Again, the implementation, which is this code here,
will usually be in a separate file from the interface,
which is this code here.
For our purposes, for teaching purposes,
we're putting it all in one file
so we can see it all at once,
and it just makes more sense for the teaching environment.
But in actual practice, you'll usually find it
much more convenient to have them separate.
So while we're talking about member functions,
there's an important distinction
that you'll need to understand: if I come down here
and I take our object, and I'm going to go ahead
and have that initialization of the object there,
and then I'm going to create a separate object,
but I'm going to call it const.
I'm going to say C1, which was our class,
and call this O2, equals O1.
And now unused variable, and that's fine.
And now I come down here and I say:
the value of O2 is get value.
When I try to build this,
you'll notice that I'm getting an error.
It says: this argument to member function get value,
has type const C1 but function is not marked as const.
That's a very confusing message.
But basically, what it's saying is that we have
a const object here, O2 is a const object,
and that we're using a method, get value,
which is not marked as const safe.
So what is const safe?
To mark a function as const safe, we need to
put the keyword const in the function's signature.
So it comes at the end of the function signature,
so it's after the parenthesis, but before the code block,
and I need to do the same down here.
Now, that function is marked as const safe,
and if we come down here to our code,
you'll notice that now I can build it and I can run it,
and it works.
So what exactly does this do?
This tells the compiler that it is safe
to call this function from a const qualified object.
And a const qualified member function cannot actually
modify anything; if I try to come in here
and say I equals seven, now when I try to build this,
it says: you cannot assign a static data member
with const member function.
And so it has told the compiler
that this is a const safe function,
you can use it with a const safe object,
and everything's going to work fine.
You can even have two different versions of a method,
for both const and non-const objects.
And this is actually very interesting here.
I can come in here and I can have exactly the same code,
except this one is not const qualified,
and I need to do the same thing here.
And now we have two different versions of the same
member function, and one will be called by
non-const qualified objects, and the other
will be called only by const qualified objects.
So in order to see the difference,
we're going to go ahead and put a puts in here.
And we'll give them semicolons so they actually compile.
There we go.
And now when I build and run, you'll notice that I'm calling
the non-const function first, because I'm first using O1,
which is a non-const object,
and calling the const function second.
So the compiler actually treats that const qualifier
as part of the function's signature.
And on const qualified objects,
it will always look for a const-qualified function.
For a non-const qualified object,
in other words, for O1, even if I don't have this,
I'm going to comment this out, the non-const qualified,
it will now call the const qualified version
of the function, so the rule of thumb is,
const functions can always be called,
and non-const functions can only be called by non-const,
or as they're often called, mutable objects.
A mutable object is an object
that does not have a const qualifier.
So this is important to remember,
if you're ever going to have const modified objects
built from your class, you need to make sure
that you have const qualified member functions
to be used by those const qualified objects.
Member functions are what make
object-oriented programming possible.
As we go through the rest of this chapter,
you'll see that most of the other features
of C++ objects are based on member functions.