Revision Exercise - 4

Exercise 1 - Classes

Part 0 - Classes and Objects

  1. What is the purpose of using classes?

  2. What is the difference between an object/instance, and a class? Show an example of creating an instance from a class.

  3. Give the class above a public member variable. Show how you can modify and access its member variable through an instance of a class.

  4. Dynamically allocate an instance of your class, storing the memory address of the instance in a pointer. Show how you can modify and access its member variable through a pointer to an instance of a class.

Part 1 - Class Access Modifiers

  1. Explain the difference between public and private class members.

  2. What are the differences between a struct and a class?

Part 2 - Class Constructors

  1. When is a constructor of a class invoked?

  2. Can multiple constructors be defined? Show an example.

  3. There are two scenarios where the destructor of a class is invoked, list and provide an example for both.

  4. When should a class implement a destructor?

Part 3 - The static Keyword

  1. What are static class members or static class functions?

  2. Is it possible to access a static class member without an instance of the class? If so, provide an example.

  3. Is it possible to invoke a static class functions without an instance of the class? If so, provide an example.

  4. What happens when you use the static keyword on a local variable within a function?

Part 4 - Size of a Class

  1. What is the result of invoking the sizeof() operator on a class?

  2. If a class has a member variable of int* which corresponds to a dynamically allocated array of integers, will the result of sizeof() vary depending on the size of the array?

Part 5 - The this Pointer

  1. In the context of a class member function, what is the this keyword?

  2. Is the this keyword available for static class functions?

Part 6 - Class Friends

  1. In the context of classes, what does the friend keyword do?

  2. Show an example of a friend function.

  3. Show an example of a friend class.

Exercise 2 - Inheritance

Part 0 - Inheritance

  1. What problem does inheritance strive to solve?

  2. Show an example of a base class Foo which publicly is inherited by derived class Bar.

Part 1 - Inheritance Access Modifiers

  1. Using the example in Part 0.2, define some private member variables in Foo. Is the class Bar able to modify or access these member variables?

  2. How can we give Bar access to these member variables, without making these member variables public?

  3. Using the example in Part 0.2, define a constructor for Foo which accepts a parameter. How can we invoke the constructor for Foo in the constructor of Bar? In other words, how do we initialise the base class from the derived class?

Part 2 - Overriding

  1. How can we override base class methods from the derived class?

  2. How can we invoke an overridden base class method, from a member function in the derived class?

Part 3 - Order of Construction and Destruction

  1. What is the order of construction for a derived class? Is the derived class constructed first, or the base class? Show an example.

  2. What is the order of destruction for a derived class? Is the derived class destroyed first, or the base class? Show an example.

Part 4 - Public and Private Inheritance

  1. How does private inheritance different to that of public inheritance?

  2. Private inheritance is not a popular pattern, what instead is a better way to express a "has-a" relationship?

Exercise 3 - Polymorphism

Part 0 - Polymorphic Behaviour

Study the below code snippet, predict what would be output when the snippet is run:

class Base {
    void foo() {
        std::cout << "I am Base" << std::endl;
    }
};

class Derived: public Base {
    void foo() {
        std::cout << "I am Derived" << std::endl;
    }
};

void invokeFoo(Base& x) {
    x.foo();
}

int main() {
    Derived derived;
    invokeFoo(derived);
}

Run the code, then explain what can be concluded based on your observations.

  1. How can we modify the classes such that "I am Derived" will be printed instead?

  2. Following this, why is it important to use the same technique for destructors? Show an example.

Part 1- Virtual Function Table

  1. Is the following statement true: The .foo() function that is to be invoked by invokeFoo(Base& x) is determined at compile time.

  2. What is the Virtual Function Table (VFT), and when is it created?

Study the following code snippet:

class Animal {
    virtual void eat() {
        std::cout << "Animal::eat" << std::endl;
    }
    
    virtual void cry() {
        std::cout << "Animal::cry" << std::endl;
    }
    
    virtual void sleep() {
        std::cout << "Animal::sleep" << std::endl;
    }
    
};

class Bear: public Animal {
    void cry() {
        std::cout << "Bear::cry" << std::endl;
    }
};

Draw a diagram showing the contents of the VFT for both the Animal and the Bear class.

Part 2 - Abstract Classes

  1. What is an abstract base class?

  2. How do you define an abstract base class?

  3. Must a derived class implement all pure virtual functions in its base class?

  4. What is the purpose of abstract base classes?

Part 3 - The Diamond Problem

  1. Illustrate the diamond problem with an example.

  2. How can the diamond problem be solved? Use the above example to show this.

Last updated

Was this helpful?