Lecture 2. Basics Part 1
Lecture 2. Basics Part 1
ENEL3CCH1
Week Two
A sample OOP application in C++
• Defines the messaging class and main program in one source file for now. Not good
practice in general, but useful for now. (Later we split them apart)
• Messaging class has private member variables and public methods. What is a
constructor?
• It includes accessor methods and constructors (default and overloaded constructor).
public:
//Accessor methods
void setMsg(std::string Msg1) { this->Msg = Msg1; } We begin with
Class definition std::string getMsg() { return Msg; }
a complete
//Method solution in a
void display() { std::cout << Msg; } single file
//constructors
Message() { this->Msg = "Empty string!!!"; }
Message(std::string Msg) { this->Msg = Msg; }
};
int main(){
Message MsgObj("Howzit!"); //instantiate the object
Main program
MsgObj.display(); //use its method
return 0;
}
#include <iostream>
Pre-processor
#include <string>
directives
class Message {
private: Private section
std::string Msg; Contains private members
(usually data)
public:
//Accessor methods
void setMsg(std::string Msg1) { this->Msg = Msg1; } Public section
Class definition std::string getMsg() { return Msg; } Contains public members
(usually methods)
//Method
void display() { std::cout << Msg; } In this first example, the
methods are all defined
Default constructor //constructors (and implicitly declared)
Message() { this->Msg = "Empty string!!!"; } in the public section of
Message(std::string Msg) { this->Msg = Msg; } the class definition. This
Constructor overload }; is done for simplicity.
Uses overloaded constructor
int main(){
Message MsgObj("Howzit!"); //instantiate the object
Main program
MsgObj.display(); //use its method
return 0;
}
main() cannot see Msg, or access it directly. It is private.
#include <iostream>
Pre-processor
#include <string> However, main() can do the following…
directives • read/modify Msg via public accessor methods, and
• Modify Msg via the public overloaded constructor
class Message {
private: Private section
std::string Msg; Contains private members
(usually data)
public:
Discussion: //Accessor methods
void setMsg(std::string Msg1) { this->Msg = Msg1; } Public section
Why bother having accessor std::string getMsg() { return Msg; }
Classwhen
methods, definition
we can just Contains public members
make all members public? (usually methods)
//Method
What is the potential void display() { std::cout << Msg; } In this first example, the
benefit of accesors? methods are all defined
//constructors (and implicitly declared)
Message() { this->Msg = "Empty string!!!"; } in the public section of
Message(std::string Msg) { this->Msg = Msg; } the class definition. This
Overloaded constructor }; is done for simplicity.
int main(){
Message MsgObj("Howzit!"); //instantiate the object
Main program
MsgObj.display(); //use its method
return 0; main() modifies Msg via the public
} overloaded constructor at instantiation
#include <iostream>
Pre-processor
#include <string> We now proceed to a formal
directives
separation of code into
class Message { different files. This has
private: advangates. Can you
std::string Msg; identify an advantage? Firstly, we want to
explicitly declare all
public: the public members in
//Accessor methods the public section of
void setMsg(std::string Msg1) { this->Msg = Msg1; } the class up here.
Class definition std::string getMsg() { return Msg; }
//Method
void display() { std::cout << Msg; }
//constructors
Message() { this->Msg = "Empty string!!!"; }
Message(std::string Msg) { this->Msg = Msg; } Then we want our
}; public member
definitions down
here, and we
scope these back
into the class.
int main(){
Message MsgObj("Howzit!"); //instantiate the object
Main program
MsgObj.display(); //use its method
#include <iostream>
#include <string> class Message {
private:
std::string Msg;
public:
void setMsg(std::string Msg1);
Explicit method
std::string getMsg(); declarations
void display(); (prototypes)
Message(); //default constructor
Message(std::string); //construct overload
};
Message::Message(std::string Msg) {
this->Msg = Msg;
int main(){
}
Message MsgObj("Howzit!"); //instantiate the object
MsgObj.display(); //use its method
return 0;
}
MyProg.cpp
#include <iostream> We have separated
#include <string>
#include “Message.h” the files, but for
#pragma once int main(){
them to work
and header Message MsgObj("Howzit!"); //instantiate the object together, additional
guards will be MsgObj.display(); //use its method preprocessor
discussed later… return 0; directives are needed
}
Message.h Message.cpp
Class header file #include “Message.h”
#pragma once
#include <iostream> Declares the class
#include <string> void Message::setMsg(std::string Msg1) { this->Msg = Msg1; }
interface… everything
the caller needs to
class Message { std::string Message::getMsg() { return Msg; }
know about the class
private:
std::string Msg; void Message::display() {
std::cout << Msg;
public: }
void setMsg(std::string Msg1);
std::string getMsg(); Message::Message() { //define default constructor
void display(); this->Msg = "Empty string!!!";
Class implementation file
Message(); //default constructor }
Message(std::string); //construct overload Contains method
}; Message::Message(std::string Msg) { implementations for the class
this->Msg = Msg; The caller does not need to
} know this stuff
Intro to Namespaces
• A feature added to C++
• Does not exist in C
A spatial A sense of
grouping belonging
:
namespace BN { //illustration of a user defined namespace
string std::string endl() { return "\n"; }
cout }
endl
:
Source file
int main(){
std::cout << "Hello World!\n";
std::cout << "Hello KZN!" << BN::endl(); //uses endl from BN
std::cout << "Hello Durban!" <<std::endl; //uses endl from std
}
Namespaces – example 1
Source file namespace BN
:
string
cout namespace BN { //illustration of a user defined namespace
endl std::string endl() { return "\n"; }
: }
int main(){
cout << "Hello World!\n";
cout << "Hello KZN!" << BN::endl(); //uses endl from BN
cout << "Hello Durban!" << endl; //uses endl from std
}
Namespaces – example 1
Source file
int main(){
cout << "Hello World!\n";
cout << "Hello KZN!" << endl(); //uses endl from BN
cout << "Hello Durban!" << endl; //uses endl from std
}
Confusion here!!!
Now we have seen by example that…
A defined
approach OOP is not a language A way of
thinking
OOP is a methodology
A system of
OBJECTs principles
Philosophical
Abstraction concepts Inheritance
Polymorphism
Encapsulation Object
Class
Abstraction
A key concept in OOP (but not limited to OOP)
Main goal: To enclose data and methods that work on the data, in
one unit
Single unit
Class definition
Data
Member variables
with defined
Data Methods
characteristics and behaviour.
Member Member
variables? functions?
Class
So you can say…
Each of these related
objects is an instance
of that class
As far as possible,
Identify classes so that they follow the…
As far as possible,
Identify classes so that they follow the…
Open-Closed principle
• Where the class is open for extension, but closed for modification.
• This allows you to add new functionality (by extension) without
changing existing code (modification).
• This makes the class easier to maintain.
Inheritance
Respectful
Confident
• Behave like and engineer should behave (Behavioural learning) Focused
Skilled
For example:
Use this to count the total number of messages sent by all instances of the class
Or use this to count the number of class instances currently in existence
For example:
Use this to print the total number of messages sent by all instances of the class
Or to print the total number of class instances in existence
• Add a destructor
that indicates the destruction of an object and the number of class instances
still left.