Chapter Eight, Gaining Proficiency with Classes and Objects
Chapter 8 is a good refresher in classes.
There is also some new stuff here.
And he sets up an example he uses for many more chapters.
Read it.
He points out that he is writing code to illustrate concepts
At times better practices will be introduced later in the discussion
He discusses the
protected
access control keyword
This is needed for inheritance so we will look at it later.
He points out that you can initialize member data when defining the member
class PersonT { ... private int age = -1; };
This is actually a preferred method for initializing values.
It avoids problems we will have later in hierarchies.
He points out that it is ok to have members call other members.
In one design philosophy this is encouraged.
You want to minimize the places for errors
If you write two pieces of code that do the same thing, this increases your chances of errors.
Calling one from the other eliminates this.
Or even building what he calls "helper" functions.
These are functions that the class needs.
But you don't want to expose to the outside world.
So declare these to be private member functions.
Why would it be bad to expose a helper function to the outside world?
He discusses the this pointer.
Really nothing new here.
he points out an error caused by poor parameter names.
But you should never see this.
Constructors
demo.cpp
.
This has a number of different versions of a person class.
The
Default constructor
is a constructor that is called by
default
when an instance of the class is created without arguments.
If you do not supply one, it will be supplied for you by the compiler.
You usually need one of these for declaring arrays
You probably want one of these.
But you do have an option.
Person1T has a default constructor.
It relies on initialization of the member data.
Person2T has a normal default constructor.
Person3T has a
constructor initialize
(see page 41).
These are useful in hierarchies.
These are the preferred
name(params): var1(value), var2(value), ... {
These are executed before any code is called.
You should put these in the order the member data is declared.
Person4T is really odd
It uses default parameters (see page 257)
These must be supplied from the right
The user still gives arguments in order, but need not supply the last of the set.
It then uses a constructor initializer to initialize the values.
This will serve as a constructor for
no parameters
a name only
a name and an age.
Since it will cover a no-parameter case, it is also a default constructor.
Person5T has a two parameter constructor
This is problematic
The compiler will not create a default constructor if any constructor is supplied.
Therefore, the only way to create an instance of this class is calling it with parameters.
Person6T is like person 5, but
We have asked the compiler to build a default constructor.
This will rely on the values set in the declaration.
Person 7 is really strange
It has a constructor,
But the default constructor has been explicitly deleted.
This is more for documentation to the reader.
You can do this with other functions as well.
In the latest version of gcc, the copy constructor for the stream class has been explicitly deleted.
Passing a stream by value is a bad thing.
So they delete it.
In this case, however it creates a problem.
The compiler still feels it might select this.
So we have no default constructor for class 7.
Note down in the program we can use an initializer for Person4,5 and 6.
A little more on constructor initializes
When C++ creates and object:
It creates all member data
Including calling the constrictor for any data members that have one.
Then calls the constructor
Thus the object is constructed BEFORE the constructor is called.
The constructor initializers are where the constructors are called
Thus you are initializing any object properly, not just changing them.
This is important in several cases (see the bottom of page 216)
A must for reference objects, these can be assigned only once
A requirement for objects that don't have default constructors.
A requirement for const data members.
And required for some classes in hierarchies.
They must initialize in the order the data members are declared.
The order for the ctor-initializer is unimportant.
If one data member relies on another, declare the one that is used for the second first.
See
ctorInit.cpp