Introduction to Programming with C++, Third Edition, Y. Daniel Liang

This quiz is for students to practice. A large number of additional quiz is available for instructors using Quiz Generator from the Instructor's Resource Website. Videos for Java, Python, and C++ can be found at https://yongdanielliang.github.io/revelvideos.html.

Many questions in this edition have been updated in the new edition. Please check with the publisher on the newest edition.

Chapter 15 Inheritance and Polymorphism


Section 15.2 Base classes and Derived classes
15.1  Object-oriented programming allows you to derive new classes from existing classes. This is called ____________.
A. encapsulation
B. inheritance
C. abstraction
D. generalization

15.2  Which of the following statements are true?
A. A derived class is a subset of a base class.
B. A derived class is usually extended to contain more functions and more detailed information than its base class.
C. "class A: public B" means A is a derived class of B.
D. "class A: public B" means B is a derived class of A.

15.3  What is the output of the following code?

  #include <iostream>
  using namespace std;

  class ParentClass
  {
  public:
    int id;

    ParentClass(int id)
    {
      this->id = id;
    }

    void print()
    {
      cout << id << endl;
    }
  };

  class ChildClass: public ParentClass
  {
  public:
    int id;

    ChildClass(int id): ParentClass(1)
    {
      this->id = id;
    }
  };

  int main()
  {
    ChildClass c(2);
    c.print();

    return 0;
  }
A. 0
B. 1
C. 2
D. Nothing

Section 15.3 Generic Programming
15.4  Suppose Circle and Rectangle classes are derived from GeometricObject and you declared

void displayGeometricObject(GeometricObject shape)
{
  cout << shape.toString() << endl;
}

Which of the following function call is correct?
A. displayGeometricObject(GeometricObject("black", true));
B. displayGeometricObject(Circle(5));
C. displayGeometricObject(Rectangle(2, 3));
D. displayGeometricObject(string());

Section 15.4 Constructors and Destructors
15.5  Are the constructors inherited by the derived class?
A. Yes
B. No

15.6  Are the destructors inherited by the derived class?
A. Yes
B. No

15.7  Suppose class A is derived from B and both A and B have no-arg constructors. To invoke B's constructor from A, use ________.
A. A(): B() { ... }
B. A(): { B(); ... }
C. B(): A() { ... }
D. B(): { A(); ... }

15.8  What is the output of the following code?

  #include <iostream>
  using namespace std;
  
  class B
  {
  public:
    ~B()
    {
      cout << "B";
    }
  };
  
  class A: public B
  {
  public:
    ~A()
    {
      cout << "A";
    }
  };
  
  int main()
  {
    A a;
    return 0;
  }
A. AB
B. BA
C. A
D. B
E. AA

15.9  What is wrong in the following code?

class Fruit
{
public:
  Fruit(int id)
  {
  }
};

class Apple: public Fruit
{
public:
  Apple()
  {
  }
};
A. The program will compile if you add a no-arg constructor for Fruit.
B. The program has a compile error because Fruit does not have a no-arg constructor.
C. The program will compile if you delete the constructor in Fruit.
D. The program will compile if you replace Apple() by Apple(): Fruit(4).

Section 15.5 Redefining Functions
15.10  Which of the following statements are true?
A. To redefine a function, the function must be defined in the derived class using the same signature and return type as in its base class.
B. Overloading a function is to provide more than one function with the same name but with different signatures to distinguish them.
C. It is a compilation error if two functions differ only in return type.
D. A private function cannot be redefined. If a function defined in a derived class is private in its base class, the two functions are completely unrelated.

15.11  Which of the following statements are true?
A. A function can be overloaded in the same class.
B. A function can be redefined in the same class.
C. If a function overloads another function, these two functions must have the same signature.
D. If a function redefines another function, these two functions must have the same signature.

15.12  To invoke the toString() function defined in GeometricObject from a Circle object c, use __________.
A. super.toString()
B. c.super.toString()
C. c.GeometricObject::toString()
D. c->GeometricObject::toString()

Sections 15.7-15.8
15.13  What will be displayed by the following code?

  #include <iostream>
  using namespace std;

  class C
  {
  public:
    string toString()
    {
      return "C";
    }
  };

  class B: public C
  {
    string toString()
    {
      return "B";
    }
  };

  class A: public B
  {
    string toString()
    {
      return "A";
    }
  };

  void displayObject(C* p)
  {
    cout << p->toString();
  }

  int main()
  {
    displayObject(&A());
    displayObject(&B());
    displayObject(&C());
    return 0;
  }
A. ABC
B. CBA
C. AAA
D. BBB
E. CCC

15.14  What will be displayed by the following code?

  #include <iostream>
  using namespace std;

  class C
  {
  public:
    virtual string toString()
    {
      return "C";
    }
  };

  class B: public C
  {
    string toString()
    {
      return "B";
    }
  };

  class A: public B
  {
    string toString()
    {
      return "A";
    }
  };

  void displayObject(C* p)
  {
    cout << p->toString();
  }

  int main()
  {
    displayObject(&A());
    displayObject(&B());
    displayObject(&C());
    return 0;
  }
A. ABC
B. CBA
C. AAA
D. BBB
E. CCC

15.15  What will be displayed by the following code?

  #include <iostream>
  using namespace std;

  class C
  {
  public:
    string toString()
    {
      return "C";
    }
  };

  class B: public C
  {
    string toString()
    {
      return "B";
    }
  };

  class A: public B
  {
    virtual string toString()
    {
      return "A";
    }
  };

  void displayObject(C* p)
  {
    cout << p->toString();
  }

  int main()
  {
    displayObject(&A());
    displayObject(&B());
    displayObject(&C());
    return 0;
  }
A. ABC
B. CBA
C. AAA
D. BBB
E. CCC

15.16  What will be displayed by the following code?

  #include <iostream>
  using namespace std;

  class C
  {
  public:
    virtual string toString()
    {
      return "C";
    }
  };

  class B: public C
  {
    string toString()
    {
      return "B";
    }
  };

  class A: public B
  {
    string toString()
    {
      return "A";
    }
  };

  void displayObject(C p)
  {
    cout << p.toString();
  }

  int main()
  {
    displayObject(A());
    displayObject(B());
    displayObject(C());
    return 0;
  }
A. ABC
B. CBA
C. AAA
D. BBB
E. CCC

15.17  What is the output of the following code?

 #include <iostream>
 #include <string>
 using namespace std;

 class Person
 {
 public:
   void printInfo()
   {
     cout << getInfo() << endl;
   }

   virtual string getInfo()
   {
     return "Person";
   }
 };

 class Student: public Person
 {
 public:
   virtual string getInfo()
   {
     return "Student";
   }
 };

 int main()
 {
   Person().printInfo();
   Student().printInfo();
 }
A. Person Person
B. Person Student
C. Stdudent Student
D. Student Person

15.18  What is the output of the following code?

 #include <iostream>
 #include <string>
 using namespace std;

 class Person
 {
 public:
   void printInfo()
   {
     cout << getInfo() << endl;
   }

   string getInfo()
   {
     return "Person";
   }
 };

 class Student: public Person
 {
 public:
   string getInfo()
   {
     return "Student";
   }
 };

 int main()
 {
   Person().printInfo();
   Student().printInfo();
 }
A. Person Person
B. Person Student
C. Stdudent Student
D. Student Person

15.19  If A is derived from B, and B is derived from C, B has a virtual function, will this function be dynamically binded?
A. Yes
B. No

15.20  If the variable that references the object for the function is not the address of the object, will this function be dynamically binded?
A. Yes
B. No

15.21  Which of the following statements are true?
A. If a function is defined virtual in a base class, it is automatically virtual in all its derived classes. It is not necessary to add the keyword virtual in the function declaration in the derived class.
B. If a function will not be redefined, it is more efficient without declaring it virtual, because it takes more time and system resource to bind virtual functions dynamically at runtime.
C. A virtual function may be implemented in several derived classes. C++ dynamically binds the implementation of the function at runtime, decided by the actual class of the object referenced by the variable.
D. The compiler finds a matching function according to parameter type, number of parameters, and order of the parameters at compile time.

15.22  Which of the following statements are true?
A. Private members can only be accessed from the inside of the class and public members can be accessed from any other classes.
B. A protected data field or a protected function in a base class can be accessed by name in its derived classes.
C. A public data field or function in a class can be accessed by name by any other program.

15.23  Analyze the following code:

  #include <iostream>
  using namespace std;
  
  class A
  {
  public:
    A()
    {
      t();
      cout << "i from A is " << i << endl;
    }
  
    void t()
    {
      setI(20);
    }
  
    virtual void setI(int i)
    {
      this->i = 2 * i;
    }
    
    int i;
  };
  
  class B: public A
  {
  public:
    B()
    {
      // cout << "i from B is " << i << endl;
    }
  
    virtual void setI(int i)
    {
      this->i = 3 * i;
    }
  };
  
  int main()
  {
    A* p = new B();
  
    return 0;
  }
A. The constructor of class A is not called.
B. The constructor of class A is called and it displays "i from A is 0".
C. The constructor of class A is called and it displays "i from A is 40".
D. The constructor of class A is called and it displays "i from A is 60".

15.24  Analyze the following code:

  #include <iostream>
  using namespace std;
  
  class A
  {
  public:
    A()
    {
      t();
      // cout << "i from A is " << i << endl;
    }
  
    void t()
    {
      setI(20);
    }
  
    virtual void setI(int i)
    {
      this->i = 2 * i;
    }
    
    int i;
  };
  
  class B: public A
  {
  public:
    B()
    {
      cout << "i from B is " << i << endl;
    }
  
    virtual void setI(int i)
    {
      this->i = 3 * i;
    }
  };
  
  int main()
  {
    A* p = new B();
  
    return 0;
  }
A. The constructor of class A is not called.
B. The constructor of class A is called and it displays "i from B is 0".
C. The constructor of class A is called and it displays "i from B is 40".
D. The constructor of class A is called and it displays "i from B is 60".

Section 15.9 Abstract Classes and Pure Virtual Functions
15.25  Which of the following is an abstract function?
A. virtual double getArea();
B. virtual double getArea() = 0;
C. double getArea() = 0;
D. double getArea();

15.26  Which of the following statements are true?
A. An abstract class is declared using a keyword abstract.
B. A class is abstract if it contains a pure virtual function.
C. An abstract class is like a regular class except that you cannot create objects from it.
D. You can declare a class abstract even though it does not contain abstract functions.

Section 15.10 Casting: static_cast versus dynamic_cast
15.27  Which of the following statements are true?
A. Assigning a pointer of a derived class type to a pointer of its base class type is called upcasting.
B. Assigning a pointer of a base class type to a pointer of its derived class type is called downcasting.
C. Upcasting can be performed implicitly without using the dynamic_cast operator.
D. downcasting must be performed explicitly using the dynamic_cast operator.

15.28  Suppose you declared GeometricObject* p = &object. To cast p to Circle, use ___________.
A. Circle* p1 = dynamic_cast<Circle>(p);
B. Circle* p1 = dynamic_cast<Circle*>(p);
C. Circle p1 = dynamic_cast<Circle*>(p);
D. Circle p1 = dynamic_cast<Circle>(p);

15.29  What will be displayed by the following code?

  #include <iostream>
  #include <string>
  using namespace std;

  class A
  {
  public:
    string toString()
    {
      return "A";
    }

  };

  class B: public A
  {
  public:
    string toString()
    {
      return "B";
    }
  };

  int main()
  {
    A* b = new B();

    cout << static_cast<A*>(b)->toString() << b->toString() << endl;

    return 0;
  }
A. AA
B. AB
C. BA
D. BB

15.30  What will be displayed by the following code?

  #include <iostream>
  #include <string>
  using namespace std;

  class A
  {
  public:
    string toString()
    {
      return "A";
    }

  };

  class B: public A
  {
  public:
    string toString()
    {
      return "B";
    }
  };

  int main()
  {
    B b;
    cout << static_cast<A>(b).toString() << b.toString() << endl;

    return 0;
  }
A. AA
B. AB
C. BA
D. BB

15.31  Choose the correct answers to address the issues in the followin code:

  #include <iostream>
  #include <string>
  using namespace std;

  class A
  {
  public:
    _Place1______ string toString()
    {
      return "A";
    }

  };

  class B: public A
  {
  public:
    _Place2________ string toString()
    {
      return "B";
    }
  };

  int main()
  {
    A* b = new B();

    cout << dynamic_cast<B*>(b)->toString() << endl;

    return 0;
  }
A. With blank for Place1 and Place2, the program will compile and run fine.
B. With Place1 replaced by virtual and Place2 blank, the program will compile, but not run.
C. With Place1 replaced by virtual and Place2 blank, the program will compile and run.
D. With Place1 replaced by virtual and Place2 virtual, the program will compile and run.