Week 8 - Gemini Flashcards

(30 cards)

1
Q

When designing a Matrix class that stores its data in a dynamically allocated 1D array (double* data), how can the element at (row_i, col_j) be accessed if nRows is the number of rows?

A

The element (i, j) can be accessed at data[j * nRows + i] (column-major) or data[i * nCols + j] (row-major, assuming nCols is number of columns). The lecture example uses data[j * nRows + i], implying column-major storage for the 1D representation.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What is ‘const overloading’ of member functions, as seen in the Matrix class example with begin() and end() methods?

A

Providing two versions of a member function with the same name and parameters, but one is a const member function (e.g., const double* begin() const) and the other is non-const (e.g., double* begin()). The const version is called on const objects and returns a pointer/reference to const, while the non-const version is called on non-const objects and allows modification.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What is the ‘Rule of Three’ in C++ class design, especially when a class manages dynamic memory (like the Matrix class)?

A

If a class has a non-trivial destructor (e.g., it deallocates dynamic memory), it usually needs to explicitly define: 1. The destructor. 2. The copy constructor. 3. The copy assignment operator (operator=). If these are not user-defined, the compiler’s default versions might lead to issues like shallow copies and double frees with dynamic memory.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

When overloading operator+= for a Matrix class as a member function, why should it typically return a reference to *this?

A

Returning Matrix& (specifically *this) allows for chaining of assignments, like (a += b) += c;, which is conventional for assignment-like operators.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

How can the function call operator operator() be overloaded for a Matrix class? What does it enable?

A

It can be overloaded as a member function, e.g., double& operator()(int r, int c); and const double& operator()(int r, int c) const;. This enables accessing/modifying matrix elements using function-call-like syntax, e.g., matrix(row, col) = value;.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What is the purpose of the std::stringstream class, and how is it typically used for building strings efficiently? Which header is needed?

A

std::stringstream allows strings to be built by inserting data into it using << (like cout). It’s more efficient than repeated string concatenation with +. After all data is inserted, the complete string is retrieved using the .str() method. Header: <sstream>.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What is ‘inheritance’ in Object-Oriented Programming? Define base class (superclass) and derived class (subclass).

A

Inheritance is a mechanism where a new class (derived class or subclass) inherits properties (data members) and behaviors (member functions) from an existing class (base class or superclass). It establishes an “is-a” relationship.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What is the syntax for declaring a class Derived that publicly inherits from a class Base?

A

class Derived : public Base { /* ... members of Derived ... */ };

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

What does public inheritance mean in terms of accessibility of base class members in the derived class?

A

public members of the base class remain public in the derived class. protected members of the base class remain protected in the derived class. private members of the base class are inherited but are not directly accessible by the derived class’s member functions.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What is the protected access specifier used for in a base class?

A

protected members are accessible within the base class itself and by member functions of any classes directly or indirectly derived from it. They are not accessible by unrelated classes or code outside the class hierarchy.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

In what order are constructors called when an object of a derived class is created?

A

The base class constructor is called first, followed by the derived class constructor. If there’s a multi-level hierarchy, constructors are called from the topmost base class downwards.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

In what order are destructors called when an object of a derived class is destroyed?

A

The derived class destructor is called first, followed by the base class destructor (the reverse order of constructor calls).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

What is ‘function overriding’ in the context of inheritance? What must be true about the function signatures?

A

Function overriding occurs when a derived class provides a specific implementation for a member function that is already defined in its base class. The function in the derived class must have an identical signature (name, parameter types, and const-ness) to the base class function.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

How can a derived class explicitly call an overridden member function from its immediate base class Base?

A

Using the scope resolution operator: Base::functionName(arguments);.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Distinguish between inheritance (‘is-a’ relationship) and composition (‘has-a’ relationship) in class design.

A

Inheritance implies that the derived class is a specialized type of the base class (e.g., a SavingsAccount is an Account). Composition means a class has a member object of another class type (e.g., a Car has an Engine). Choose inheritance for specialization and polymorphism; choose composition for reusing functionality by embedding.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

What is ‘polymorphism’ in C++? What does it allow you to do?

A

Polymorphism (meaning “many forms”) allows objects of different derived classes to be treated through a common base class interface, typically using base class pointers or references. The same function call can behave differently depending on the actual runtime type of the object.

17
Q

What is a virtual function in a base class, and how does it enable polymorphism?

A

A virtual function is a member function declared with the virtual keyword in a base class. It signals that derived classes might override it. When a virtual function is called through a base class pointer or reference, the call is resolved at runtime (late binding) to the version of the function in the actual type of the object, enabling polymorphic behavior.

18
Q

Explain ‘late binding’ (dynamic dispatch) versus ‘early binding’ (static dispatch).

A

Early binding: The function call is resolved at compile time based on the static type of the pointer/reference. This is the default for non-virtual functions. Late binding: The function call is resolved at runtime based on the actual dynamic type of the object being pointed/referred to. This occurs for virtual functions called via base class pointers/references.

19
Q

What is ‘upcasting’? Is it generally safe?

A

Upcasting is the act of treating a pointer or reference to a derived class object as a pointer or reference to its base class type (e.g., Base* b_ptr = &derived_obj;). It is generally safe because a derived class object “is-a” base class object and contains all its members.

20
Q

What is ‘object slicing’? When does it occur, and why is it problematic for polymorphism?

A

Object slicing occurs when a derived class object is assigned or copied by value to a base class object. Only the base class part of the derived object is copied, and the derived-specific parts are ‘sliced off’. If virtual functions are then called on this base class object, they will resolve to the base class versions, losing polymorphic behavior.

21
Q

How do you achieve polymorphic behavior correctly, avoiding object slicing?

A

By using pointers or references to the base class to refer to derived class objects.

22
Q

What is a ‘pure virtual function’? What is its syntax, and what effect does it have on a class?

A

A pure virtual function is a virtual function in a base class for which the base class provides no implementation. Syntax: virtual ReturnType functionName(parameters) = 0;. Its effect is that it makes the class an ‘abstract base class’.

23
Q

What is an ‘abstract base class’ (ABC)? Can you create instances of an ABC?

A

An ABC is a class that has at least one pure virtual function. You cannot create direct instances (objects) of an ABC. It’s meant to be used as a base class for other classes to derive from.

24
Q

What is an ‘interface class’ (or pure abstract class)?

A

A class that contains only pure virtual functions (and typically a virtual destructor) and no data members. It defines a contract or interface that derived classes must implement.

25
Why should the destructor of a base class be declared `virtual` if the class is intended to be a base for polymorphic deletion?
If you `delete` a derived class object through a base class pointer and the base class destructor is *not* `virtual`, only the base class destructor is called. This can lead to resource leaks if the derived class had its own resources to clean up (e.g., memory allocated in its constructor). A `virtual` destructor ensures that the correct sequence of destructors (derived then base) is called.
26
For the `Shape` class in Practical5 Problem 1, which has `virtual double area() const = 0;`, what does `= 0` signify?
It signifies that `area()` is a pure virtual function, making `Shape` an abstract base class. Derived classes like `Triangle` or `Rectangle` are *required* to provide their own implementation (override) of the `area()` function.
27
How would you store objects of different `Shape` derived classes (Triangle, Rectangle, Circle) in a single collection to process them polymorphically (e.g., to print their areas)? (Practical5 Problem 1)
Store them as pointers (or smart pointers) to the base class `Shape` in a container like `std::vector`. Then, when you iterate through the vector and call `shape_ptr->area()`, the correct `area()` function for the actual object type (Triangle, Rectangle, or Circle) will be invoked due to polymorphism.
28
In Practical5 Problem 1, the `BadSquare` derived from `Rectangle` has an issue if `SetHeight` is called. What OOP concept helps resolve this by making `GoodSquare` have a `Rectangle` member instead?
Composition ('has-a' relationship). Instead of `BadSquare` 'is-a' `Rectangle` (inheritance), `GoodSquare` 'has-a' `Rectangle` as a private member, allowing it to control the interface and ensure square properties (width == height) are maintained.
29
For Practical5 Problem 2 (numerical integration with `RealFunction` interface), how does using an interface class `RealFunction` with a pure virtual `evaluate(double x) = 0` allow a generic `integral` function to work with different mathematical functions?
Specific mathematical functions (like `SinFunction`) can be implemented as classes derived from `RealFunction`, each providing its own `evaluate` method. The generic `integral(RealFunction& f, ...)` function can then take a reference to any `RealFunction` object and call `f.evaluate(x)` polymorphically to get the value of whichever specific function was passed.
30
In the Person-Employee-Manager hierarchy (Practical5 Problem 3), if `print()` is a virtual function, and you have a `std::vector staff_list`, what happens when you call `staff_list[i]->print()`?
Polymorphism occurs. The version of `print()` specific to the *actual runtime type* of the object pointed to by `staff_list[i]` (be it Person, Employee, Manager, or Clerk) will be executed.