-
OOP Design principles
- Consistent abstraction in same class
- Encapsulate implementation details
- USe inheritance to simplify design and reuse code
- Information hiding
- Keep coupling loose
-
Examples of coupling (Classes A and B)
- Calling a member of A in B
- Creating an instance of B in A
- Using a A as a parameter in B's methods
-
Bad coupling practice(s)
Semantic/behavioral coupling
-
Examples of good coupling
- Simple data parameters
- Simple object - instantiates an object
-
What is semantic coupling?
Assuming the behavior of a coupled class or it's methods
-
Examples of semantic coupling (Classes A and B)
- If class A has foo and bar methods, assuming foo will call bar internally in B (i.e not calling it explicitly in B)
- B assuming methods exist for all instances of A
- Class A setting a control flag of B
- Some method of B uses global data after a method of A modifies it
- Class A passes class C to B, but assumes only some fields will be used and fails to instantiate those that it doesn't expect B to use
-
Why is semantic coupling bad?
- Assumptions about class implementations
- Likely implementations will change in future
- Harder to track down problems
-
What are abstract types?
A collection of data and operations that work on some data
-
Properties of abstract data types
- Hidden implementation details (work with abstraction instead)
- Easy to change implementation
-
How to use "has a" relationships
Use containment (data members)
-
Types of object relationships
- Containment "has a"
- Inheritance "is a"
-
How to override an interface?
Use containment or inheritance
-
If a base and derived class have a common method, which is called by default?
The derived class implementation
-
How to access base class implementation of a shared method?
- Use scoping
- baseName::methodName()
-
What is not inherited by a derived class?
- Overridden functions
- Constructors
- Destructors
- Assignment operator
-
How do friend functions handle inheritance?
Friends of the base class are not automatically friends of the derived class
-
If A is derived from B,
Can A be converted to B?
Can be be converted to A?
- A can be converted to B
- but B cannot be converted to A
- A similar relationship is true for pointers
-
How are constructors called in deeply inherited systems?
The constructor from the deepest base class is called first and they are called in depth order
-
Is it necessary to call the base class constructor manually?
No, it will be called automatically unless otherwise stated
-
How to set parameters for a base class constructor
- Use initialization list
- Derived::Derived(...) : Base{ <params> } { ...
-
What order are destructors called in?
Base class first and so on...
-
What can access protected members
- Current class
- Derived classes
- Friend functions
-
Forms of inheritance
- Specialization - New attributes and behaviors (public inheritance)
- Specification - Base classes specifies some behaviour, but does not implement (public inheritance)
- Restriction - Restrict base class methods (protected or private inheritance)
-
Types of binding
- Static (Compile time - Function overloading)
- Dynamic
-
How is dynamic binding achieved in C++
- Using virtual functions
- Matching functions in base classes are automatically declared virtual
-
How to specify which version of a virtual function to call?
Use a pointer of the type
-
Properties of virtual destructors
Base class destructors should always be virtual (making it virtual allows delete to call correct destructor)
-
What is an abstract class
A class that contains at least one pure virtual funciton
-
What is a pure virtual function
A function that is not implemented in a class
-
How to determine runtime type of an object?
- Include <typeinfo>
- typeID(*<object>) //returns runtime type (must dereference param)
-
How to specify multiple inheritance
Class A : B, C, ... {
|
|