- The compiler uses a different algorithm to locate member variables and regular member functions than it does to locate polymorphic member functions.
- True
- False
ans: a
- Virtual functions allow you to
- create an array of type pointer-to-base c1as that can hold pointers to derived classes.
- create functions that can never be accessed.
- group objects of different classes so they can all be accessed by the same function code.
- use the same function call to execute member functions of objects from different classes.
ans: d
- A pointer to a base (super) class can point to objects of a derived (sub) class.
- True
- False
ans: a
- Write a prototype for a virtual function called foo() that returns type
void
and takes one argument of type int
.
ans: virtual void foo(int);
- Deciding what function a particular function call executes, after a program starts running, is called _________________.
ans: polymorphism, late binding, run-time binding, dynamic binding, or dynamic dispatch
- Write the declaration for a pure virtual function named bar() that returns
void
and takes no arguments.
ans: virtual void bar()=0;
- A pure virtual function is a virtual function that (mark all that apply)
- causes its class to be abstract.
- returns nothing.
- is used in a base (super) class.
- takes no arguments.
ans: a and c
- An abstract class is useful when
- no classes should be derived from it.
- there are multiple paths from one derived class to another.
- no objects should be instantiated from it.
- you want to defer the declaration of the class.
ans: c
- Which of the following is not one of the defining features of the object-oriented model?
- inheritance
- association
- encapsulation
- polymorphism
ans: b. The three "crown jewels" characterizing the object-oriented paradigm are encapsulation, inheritance, and polymorphism
- Examine the following class definition:
Public class Insect
{ public:
virtual void sting(int howHard) { ... }
virtual int sting(double howHard) { ... }
};
Function sting is
- a correctly overridden function
- a correctly overloaded function
- an erroneously overridden function
- an erroneously overloaded function
ans: b. Overloading is a within-class concept. The argument lists must be unique but the return types may be different. (Early in the development of C++, the return types also had to be the same but this requirement was dropped long enough ago that you should no longer see it mentioned in texts.)
- Examine the following class definitions:
class Insect
{ public:
void sting(int howHard) { ... }
}
class Spider : public Insect
{ public:
int sting(int howHard) { ... }
};
Function sting is
- a correctly overridden function
- a correctly overloaded function
- an erroneously overridden function
- an erroneously overloaded function
ans: c. Overriding is a between-class concept. The classes must be related through inheritance (also includes classes with a common ancestor), each has a function with the same name, the argument lists must be the same, and the return types must also be the same.
- Polymorphism in C++ requires ALL of the following:
- Two or more classes related through inheritance
- Address variable (pointer or reference)
- An object up-cast
- Function override
- Virtual functions
- True
- False
ans: a. These concepts are tested in the next questions.
- The function calls in main invoke which functions?
class Parent
{
public:
void funcA();
virtual void funcB();
void funcC();
};
class Child : public Parent
{
public:
void funcA();
virtual void funcB();
};
int main()
{
Parent* P1 = new Parent;
Parent* P2 = new Child;
Child* C = new Child;
P1->funcA();
P1->funcB();
P1->funcC();
return 0;
}
- Parent::funcA; Parent::funcB; Parent::funcC
- Child::funcA; Child::funcB; Parent::funcC
- Parent::funcA; Child::funcB; Parent::funcC
- Parent::funcA; Child::funcB; Child::funcC
- Child::funcA; Child::funcB; Child::funcC
ans: a. The pointer variable (P1) and the object are both type Parent: all functions called are from the Parent class.
- The function calls in main invoke which functions?
class Parent
{
public:
void funcA();
virtual void funcB();
void funcC();
};
class Child : public Parent
{
public:
void funcA();
virtual void funcB();
};
int main()
{
Parent* P1 = new Parent;
Parent* P2 = new Child;
Child* C = new Child;
P2->funcA();
P2->funcB();
P2->funcC();
return 0;
}
- Parent::funcA; Parent::funcB; Parent::funcC
- Child::funcA; Child::funcB; Parent::funcC
- Parent::funcA; Child::funcB; Parent::funcC
- Parent::funcA; Child::funcB; Child::funcC
- Child::funcA; Child::funcB; Child::funcC
ans: c
The pointer variable (P2) is of type Parent but the object is an instance of Child. funcB is virtual and its call is determined by the object: Child. funcA and funcC are not virtual and their calls are determined by the pointer variable: Parent.
- The function calls in main invoke which functions?
class Parent
{
public:
void funcA();
virtual void funcB();
void funcC();
};
class Child : public Parent
{
public:
void funcA();
virtual void funcB();
};
int main()
{
Parent* P1 = new Parent;
Parent* P2 = new Child;
Child* C = new Child;
C->funcA();
C->funcB();
C->funcC();
return 0;
}
- Parent::funcA; Parent::funcB; Parent::funcC
- Child::funcA; Child::funcB; Parent::funcC
- Parent::funcA; Child::funcB; Parent::funcC
- Parent::funcA; Child::funcB; Child::funcC
- Child::funcA; Child::funcB; Child::funcC
ans: b
feedback:
general: The pointer variable (C) and the object are of type Child. funcA and funcB are from the Child class; however, Child does not override funcC, which is inherited from Parent.
- The function calls in main invoke which functions?
class Parent
{
public:
void funcA();
virtual void funcB();
void funcC();
};
class Child : public Parent
{
public:
void funcA();
virtual void funcB();
};
int main()
{
Child C;
Parent P = C;
P.funcA();
P.funcB();
P.funcC();
return 0;
}
- Parent::funcA; Parent::funcB; Parent::funcC
- Child::funcA; Child::funcB; Parent::funcC
- Parent::funcA; Child::funcB; Parent::funcC
- Parent::funcA; Child::funcB; Child::funcC
- Child::funcA; Child::funcB; Child::funcC
ans: a. The object assignment (P = C) is valid. It results in "object slicing." The part of the Child object that is not a Parent is sliced off and discarded. Polymorphism is only possible through address variables (either a pointer or a reference).
- What gets printed out by the code listed below the classes (i.e., below the line)?
class Animal
{ public:
virtual void whoAreYou() { cout << "an
Animal\n";}
};
class Insect : public Animal
{ public:
void whoAreYou() { cout << "an Insect\n";}
};
class Spider : public Insect
{ public:
void whoAreYou() { cout << "a Spider\n";}
};
--------------------------------------------------
Animal* a = new Insect;
Animal* i = new Spider;
Insect* s = new Spider;
a->whoAreYou();
i->whoAreYou();
s->whoAreYou();
- an Insect, a Spider, a Spider
- an Animal, an Animal, an Insect
- an Animal, an Insect, an Animal
- an Insect, an Insect, a Spider
- an Animal, an Animal, an Animal
ans: a. The object on the right side of the assignment operator determines which function is called.
- Fill in the blanks to complete
- The Employeeclass initializer list
- The SpecialEmployee class initializer list
- The SpecialEmployee class cal_pay function. A SpecialEmployee's is their salary plus a bonus.
The highlighted labels are not part of the program.
class Employee
{
private:
double salary;
public
Employee(double s) : (a) salary(s) {};
virtual double calc_pay() { return salary / 24; }
};
class SpecialEmployee : public Employee
{
private:
double bonus;
public:
SpecialEmployee(double b, double s) : (b) Employee(s), bonus(b) {}; // Employee(s) must be first in the list
double calc_pay() { (c) Employee::calc_pay + bonus; }
};