0% found this document useful (0 votes)
27 views38 pages

C++ Object-Oriented Design Principles

Uploaded by

Jessica Milner
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views38 pages

C++ Object-Oriented Design Principles

Uploaded by

Jessica Milner
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 38

C++

From Basics to OOD


Object-Oriented Design Goals
Object-Oriented Design Goals

Robustness – capable of handling unexpected inputs that are


not explicitly defined for its application

Adaptability – needs to be able evolve over time in response to


changing conditions in its environment

Reusability – the same code should be usable as a component


of different systems in various applications
Object-Oriented Design Principles
Object-Oriented Design Principles
Abstraction - distill a complicated system down to its most fundamental parts and
describe these parts in a simple, precise language. Abstraction means displaying
only essential information and hiding the details. Typically, describing the parts of
a system involves naming them and explain their functionality.

Applying the abstraction paradigm to the design of data structures gives rise to
abstract data types (ADT). An ADT is a mathematical model of a data structure
that specifies the type of data stored, the operations supported on them, and the
types of the parameters of the operations.

An ADT specifies what each operation does, but not how it does it.
Object-Oriented Design Principles
In C++, the functionality of a data structure is expressed through the public
interface of the associated class/classes that define the data structure

Abstraction using Classes: We can implement Abstraction in C++ using


classes. Class helps us to group data members and member functions using
available access specifiers. A Class can decide which data member will be
visible to outside world, and which is not.

Abstraction in Header files: One more type of abstraction in C++ can be


header files.
Object-Oriented Design Principles
● Abstraction using access specifiers. Access specifiers are the main pillar
of implementing abstraction in C++. We can use access specifiers to enforce
restrictions on class members. For example:

○ Members declared as public in a class, can be accessed from anywhere in the program.

○ Members declared as private in a class, can be accessed only from within the class. They are
not allowed to be accessed from any part of code outside the class.

○ Members declared as protected are inaccessible outside the class, but they can be accessed by
any subclass(derived class) of that class.
Object-Oriented Design Principles
● Advantages of Data Abstraction:

○ Helps the user to avoid writing the low-level code

○ Avoids code duplication and increases reusability.

○ Can change internal implementation of class independently without affecting the user.

○ Helps to increase security of an application or program as only important details are provided to
the user.
Object-Oriented Design Principles
● Encapsulation - different components of a software system should not reveal
the internal details of their respective implementations. Encapsulation is
defined as binding together the data and the functions that manipulates
them. In C++ encapsulation can be implemented using Class and access
modifiers.

● Modularity - the process of decomposing a problem (program) into a set of


modules so as to reduce the overall complexity of the problem
Hierarchical Organization
Structural components of a software package organize in
hierarchical fashion, which groups similar abstract definitions
together in a level-by-level manner.

A design pattern describes a solution to a “typical” software


design problem.
Inheritance and Polymorphism
The object-oriented paradigm provides a modular and
hierarchical structure for reusing code trough a
technique called inheritance.
Inheritance and Polymorphism
● The capability of a class to derive properties and
characteristics from another class is called
Inheritance
○ Sub Class: The class that inherits properties from another
class is called Sub class or Derived Class.

○ Super Class: The class whose properties are inherited by


sub class is called Base Class or Super class.
Inheritance and Polymorphism
● Modes of Inheritance
○ Public mode: If we derive a sub class from a public base class. Then
the public member of the base class will become public in the derived
class.

○ Protected mode: If we derive a sub class from a Protected base class.


Then both public member and protected members of the base class will
become protected in derived class.

○ Private mode: If we derive a sub class from a Private base class. Then
both public member and protected members of the base class will
become Private in derived class.
Inheritance and Polymorphism
● The word polymorphism means having many forms. In simple words, we
can define polymorphism as the ability of a message to be displayed in more
than one form.
● Polymorphism is the ability to determine which of the several operations
with the same name is appropriate; a combination of static (the compile-
time determination of which implementation of an operator is appropriate)
and dynamic (the run-time determination of which implementation of an
operator is appropriate) binding

○ Function Overloading: When there are multiple functions with same name but different
parameters then these functions are said to be overloaded. Functions can be overloaded by
change in number of arguments or/and change in type of arguments

○ Operator Overloading: C++ also provide option to overload operators. For example, we can
make the operator (‘+’) for string class to concatenate two strings.
// Person (base class)

Inheritance - a class Person {


private:

mechnism is used with a string name; // name

hierarchy of classes by which


string idNum; // university ID number
public:

each descendant class void print(); // print information

inherits the properties of its


string getName(); // retrieve name
};

ancestor classes
// Student (derived from Person)
class Student : public Person {
Example private:
string major; // major subject
int gradYear; // graduation year
public:
void print(); // print information
void changeMajor(const string& newMajor); // change major
};
Person person("Mary", "12"); // declare a Person

Inheritance
Student student("Bob", "98", "Math"); // declare a Student
cout << student.getName() << endl; // Person::getName()
person.print(); // Person::print()
student.print(); // Student::print()

Usage // person.changeMajor("Physics"); // ERROR!


student.changeMajor("English"); // okay
Person* pp[100]; // array of 100 Person pointers
pp[0] = new Person(...); // add a Person (details omitted)
pp[1] = new Student(...); // add a Student (details omitted)

Inheritance cout << pp[1]−>getName() << '\n'; // okay


pp[0]−>print();
pp[1]−>print();
// calls Person::print()
// also calls Person::print()

Static Binding pp[1]−>changeMajor("English"); // ERROR!

When determinig which // Since pp[1] is declared to be a pointer to a Person, the


member function to call, C+ members for that class are used

+’s default action is to


consider an object’s
declared type, not its actual
type.
class Person {
virtual void print() { ... }
};

class Student : public Person {


virtual void print() { ... }

Inheritance
};

Person* pp[100]; // array of 100 Person pointers


pp[0] = new Person(...); // add a Person (details omitted)

Dynamic Binding pp[1] = new Student(...); // add a Student (details omitted)


pp[0]−>print(); // calls Person::print()
An object’s contents pp[1]−>print(); // calls Student::print()

detrmine which member // pp[1] contains a pointer to an object of type Student, and
function is called // by the power of dynamic binding with virtual functions, the
// function Student::print will be called
Templates
● Templates are a feature in C++ that permit code to be more reusable.
● They have blanks, called parameters, that can be automatically filled
in with type names at compile time. The compiler generates multiple
versions of a class type or a function by allowing parametrized types
● Rather than having to define separate classes for lists of integers,
doubles, Circles, Dogs, Cats, etc., we can define a single List template.
○ A user of the template can supply the name of the class that will be the data in
list nodes.
○ The compiler handles the substitution of the class name specified by the user
for the parameter into the template definition.
○ Result is a List class specialized for the user’s class.

19
Limitations of Template

● A class used as a template parameter must meet certain


requirements.

● Must implement all operators used by the template methods.

○ Typically

■ = (Assignment operator)

■ Copy constructor

20
Templates
● We have two kinds of templates in C++.
○ Function templates.

○ Class templates.
● In each, parameters can be specified for one or more types.
○ The parameters are used as if they were real type names.

● The compiler substitutes real type names, specified by the


user, for the parameters when the template is used.

21
C++ Templates
● The word template is a C++ keyword

● In front of a function definition, it specifies that what


follows is …
○ a pattern for a function definition
○ not a real function definition.

● Type parameters appear within angle brackets ( < > ) before the
function definition.

● Normal function parameters appear within parentheses, as in


normal function definitions. 22
Caution
● A function template cannot be split across files.

○ Specification and implementation must be in the same file.

○ Just a .h file. No .cpp file.

23
template <typename T>
T genericMin(T a, T b) { // returns the minimum of a and b

Templates
return (a < b ? a : b);
}

cout << genericMin(3, 4) << ' '// =genericMin<int>(3,4)

Function Templates << genericMin(1.1, 3.1) << ' ' // =genericMin<double>(1.1, 3.1)
<< genericMin('t', 'g') // =genericMin<char>('t','g')
<< endl;
template <typename T>
class BasicVector {
public:
BasicVector(int capac = 10);
T& operator[](int i) {
return a[i];
}
private:

Templates
T* a;
int capacity;
}

template <typename T>


Class Templates // constructor
BasicVector<T>::BasicVector(int capac) {
capacity = capac;
a = new T[capacity]; // allocate array storage
}

BasicVector<int> iv(5); // vector of 5 integers


BasicVector<double> dv(20); // vector of 20 doubles
BasicVector<string> sv(10); // vector of 10 strings
class MathException { // generic math exception
public:
MathException(const string& err) : errMsg(err) { }
string getError() { return errMsg; } // access error message
private:
string errMsg; // error message

Exceptions
}

class ZeroDivide : public MathException {


public:
ZeroDivide(const string& err) : MathException(err) { }
Creating Exceptions };

class NegativeRoot : public MathException {


public:
NegativeRoot(const string& err) : MathException(err) { }
};
try {
// ... application computations

Exceptions
if (divisor == 0) // attempt to divide by 0?
throw ZeroDivide("Divide by zero in Module X");

} catch (ZeroDivide& zde) {


// handle division by zero
Try and Catch } catch (MathException& me) {
// handle any math exception other than division by zero
}
SOLID Principle
SOLID is an acronym for the first five object-oriented design (OOD)
principles
● Single responsibility principle
○ a class should have only a single responsibility
○ In other words, a class should only have one purpose and shouldn't do more than
just that purpose, so when a change in this purpose is needed, we have exactly
one class to modify.
● Open/closed principle
○ Software entities should be open for extension, but closed for modification
● Liskov substitution principle
○ Objects in a program should be replaceable with instances of their subtypes
without altering the correctness of that program
● Interface segregation principle
○ Many client-specific interfaces are better than one general-purpose interface
● Dependency inversion principle
○ This principle states that a higher level-module should not depend on a lower-level
SOLID - Single Responsibility Principle
A responsibility can be defined as a reason for change

For example: It would be a good idea to separate the social media


integration responsibility from the other parts of the system, as we
should always be prepared for external changes.
SOLID - Open-Closed Principle
Open for extension

● This ensures that the class behavior can be extended.


● As requirements change, we should be able to make a class behave
in new and different ways, to meet the needs of the new
requirements.

Closed for modification

● The source code of such a class is set in stone


● No one is allowed to make changes to the code.
SOLID - Liskov Substitution Principle
Derived classes must be substitutable for their base classes

For example:

● Assume your base class works with a member int.


● Now your subtype requires that int to be positive.
● This is strengthened pre-conditions, and now any code that worked
perfectly fine before with negative ints is broken.
SOLID - Interface Segregation Principle
Make fine grained interfaces that are client specific

Clients should not be forced to implement interfaces they do not use

It is better to have many smaller interfaces, than fewer, fatter


interfaces.
SOLID - Dependency Inversion Principle
Depend on abstractions, not on concretions

High level modules should not depend upon low level modules. Both
should depend upon abstractions.

Abstractions should not depend upon details. Details should depend


upon abstractions.

By depending on higher-level abstractions, we can easily change one


instance with another instance in order to change the behavior
Questions
1. Draw a class inheritance diagram for the following set of classes.
○ Class Goat extends Object and ads a member variable tail and functions milk and
jump

○ Class Pig extends Object and ads a member variable nose and functions run and
jump

○ Class Horse extends Object and ads a member variables height and color, and a
functions run and jump

○ Class Racer extends Horse and adds a function race

○ Class Equestrian extends Horse and adds a variable weight and functions trot and
isTrained
Questions
2. Give three examples of life-critical software applications.
Things you need for this class
Access to a GCC (GNU Compiler Collection) or Clang/LLVM compiler for
compiling programming projects, example code, and other source
materials distributed throughout the semester. This class will be using
C++17 standards for programming.

Access to a source code editor for writing code. Though you are not
prohibited from using IDE (Integrated development environment), you
will be personally responsible for removing any extra files/code that
IDEs can sometimes include. Suggested editors: VSCode, Atom, Sublime
Text, TextMate, Notepad++, Emacs, Vim, Nano
Visual Studio Code (VS Code)
Visual Studio Code (VS Code)

Get VS Code: https://code.visualstudio.com

Getting Started: https://code.visualstudio.com/docs/introvideos/basics

Using C++ with VS Code:


https://code.visualstudio.com/docs/languages/cpp

You might also like