The purpose of this quiz is to give you a chance to focus your knowledge of intermediate classes in C++.
How does overloading apply to class constructors?
The constructors must all be named after the class for which they construct. Therefore, to provide different initialization patterns for the programmer using our class, we have to overload the constructors with different argument lists — either different types or different numbers of arguments.
If the definition for a method is placed in the _____ then that method will be automatically _____. You don't even need to supply the keyword required for normal functions to be sped up this way.
The keyword const can be placed after a method header to specify that the calling object won't be changed. This is important because objects are often passed to functions as constant reference instead of by value to both speed the function call and still ensure the object's data can't be changed. If a method doesn't have this keyword on its header, it cannot be called with such an object.
This is an application of the principle of const correctness. Luckily, once we promise not to change the calling object, the compiler checks this and — having verified our pledge — deigns to allow the call. (Silly paranoid compiler...*shakes head* *chuckle*)
In addition to the number and types of a function's arguments, the placement of this keyword will also be used when determining overloadability. This means a class can have two functions with the exact same argument lists and only differ in the presence or absence of the keyword.
TRUE✓ | FALSE✗ | classes can be passed by reference or value just as built-in types may. |
---|---|---|
TRUE✓ | FALSE✗ | You can even return a class object from a method. |
TRUE✓ | FALSE✗ | This is often done so that class methods can more accurately emulate the built-in types behavior with similar operators (Add/+, Multiply/*, etc.). |
TRUE✗ | FALSE✓ | In particular, we always want to change the operands' values when (for instance) adding two Rational number objects. |
We know that private data of a class cannot be accessed directly from outside the class. That is why we have mutator functions in the class, after all. We also know that methods can access such data directly without problems. This is because they are inside the class. To make a function outside the class able to access such data directly, we can make it a friend of the class. This is still safe, since the class programmer/designer writes such functions. It is NOT done by another programmer after the class is done/shipped. This makes these special functions execute faster and more efficiently (without having to resort to special method calls).
Show the definition of a method to input an object of the class Rational.
bool Rational::input(void) { long n, d; char t; cin >> n >> t >> d; return !cin.fail() && t == '/' && set(n,d); }
Now show an example of a call to this method. Be sure to include any declarations and/or supporting code needed.
Rational a; cout << "Enter fraction: "; while ( ! a.input() ) { // cin.clear, cin.ignore, cerr, cout }
Show the definition of a method to calculate the midpoint of two 2D Point objects.
Point Point::midpoint(const Point & p) const { return Point((x+p.x)/2, (y+p.y)/2); }
Now show an example call to this method. Don't forget to show any necessary supporting declarations and/or other code.
Point a, b, c; c = a.midpoint(b);
What compiler inefficiency is the constructor initializer list aimed at eliminating? (I.E. What will the compiler do between the creation of a class object's memory and the execution of your constructor's body that is most often a waste of our user's time?)
The compiler wants to initialize all of the class
object's member variables to their zero or default
state before running the body of the constructor.
This often leads to member variables being
initialized twice — a terrible slowdown. The
member initialization list, if present, will tell
the compiler to forgo its defaulting behavior and
instead just initialize the member variables as
directed in the list. This can cut the speed of
the construction process in half for many
constructors.
Show an example of this for a Time class constructor. Make sure to point out in your example code how the inefficiency has been removed.
Time::Time(const Time & t) : hour(t.hour), min(t.min), sec(t.sec) { // body is empty and needs to do no work since // it was all accomplished in the init list // above }