Saturday, August 7, 2010

C++: The car class part 3: Accessors and mutators

Last time, we learned how to construct our car class. This time, let's find
out how to obtain properties about a given object and setting its properties
based on our input.
Note: Some of the function names may differ from those that I've declared
earlier.


Let's return to the declaration of a car - a 2008 Ford Mustang, but let's
say if we don't know what the released date of that car is. How do we find
out various properties i.e. values in a member variable for our car? This is
done through accessors. As the name implies, an accessor "accesses" the
private data of our object (encapsulated member variables) and returns
whatever information we need.
A typical accessor looks like a regular function with a return type, a
function name (with or without arguments, mostly without) and a return
value. So, for instance, if we want an accessor to tell us what the model of
our car we are dealing with is, we can say in English:
Can you return to me a string for the model of our car?
In C++, this is translated as:
string Car::get_model()
{
return model;
}
As we've seen before, since we are dealing with a member function of our own
class, we need to provide a scope resolution operator. But here, we need to
type that in right after typing the return type, then the object name
followed by the operator (::). In our context, the only thing that this
function (accessor) would do is tell me the model of our car, as seen below:
Suppose if I want to get the model of a car object called "my_car" and store
it in a string variable called car_model. I can do it using the following
code:
In English: Create a string variable called "car_model" and assign to it the
string returned by the get_model function of our car object called "my_car".
In C++ (in main):
string car_model = my_car.get_model();
Noticed something familiar? As you might have guessed, my_car is our car
object, and the "dot" operator tells us that get_model is a member function
of our car class. So, in this situation, the string variable (car_model)
would be initialized into whatever is returned by this accessor function (in
our example, a "Mustang).

Another example: Suppose I want to find out when a particular car model
(Ford Mustang) was released. To help me out here, I need to create another
accessor function to tell me of this fact, which would be appropriately
called get_release_year that would return an int of model year. Can you tell
me how you would write this accessor? To help you solve this problem, I will
not write the accessor here - it's up to you to design the accessor based on
the following: the year variable in the car object is called release_date,
and the accessor does not take any arguments. After you're done, you need to
create an int object to store whatever is returned by this accessor
function.

Now we know what the release date and the model of our car is, how do we set
our own input as a car property e.g. a different release year, different
manufacturer, etc.? This is done through mutators - to assign something from
one thing to another. Unlike accessors, we don't need to return anything
e.g. a return type of "void" would be used because all we are doing is just
assigning our own data as part of an object.

For instance, if I want to tell the computer to change the release year of a
car, I can ask the program to get my input and assign it to the release_date
property of our car class. In English, this could be done as follows:
* Create an int called year that will store the new release year of our car.
* Have the user enter the new release year, then pass it to our mutator to
be set as the new release date of our car.
A bit complicated, but I'm sure this can be done. All we need is the
following four lines of C++ code (again, scope resolution operator comes
in):
void Car::set_release_date(int & d)
{
release_date = d;
}
The code above did what it was supposed to do - get our input and assign it
to the release_date member variable of our car. But how do we make it
"interactive" e.g. get the actual input? Let's use my_car object once again
on the following C++ code:
int year; // The new release date of our car.
cout << "What is the release date of this car?" << endl;
cin >> year;
my_car.set_release_date(year);
As you can see, we are taking the value stored on "year" and assigning it to
the member variable.

Another example: Suppose if I want to change the manufacturer and model of
our car. Try to come up with your own mutator for these ones using the
following hints: the target variables are named "model" and "manufacturer",
respectively. We want to make sure that there would be two mutators - one
for each of our member variables. Create a mutator function to take a string
argument and set it to these two member variables. Then create a block of
main() that will ask the user to type a string for model and manufacturer
and set it to the member variables of our my_car object. Again, I'll not
give you my code - just want to find out if you've understood it. Don't
forget: in the mutator functions, you need the scope resolution operator...

I think that provides a general overview on accessors and mutators. I'll
come back and write few things about these two in a sec...
// JL

No comments:

Post a Comment