2 CPP
2 CPP
Yulei Sui
University of Technology Sydney, Australia
1
Software Verification [Link]
Introduction to C++ Programming
What is C++?
• A general-purpose programming language that was developed as an
enhancement of the C language to include object-oriented paradigm.
2
Software Verification [Link]
Introduction to C++ Programming
What is C++?
• A general-purpose programming language that was developed as an
enhancement of the C language to include object-oriented paradigm.
Why learn C++?
• Language for building system software (e.g., operating systems, web
browsers, game engines, database engines, language runtimes and
cloud/distributed systems)
2
Software Verification [Link]
Introduction to C++ Programming
What is C++?
• A general-purpose programming language that was developed as an
enhancement of the C language to include object-oriented paradigm.
Why learn C++?
• Language for building system software (e.g., operating systems, web
browsers, game engines, database engines, language runtimes and
cloud/distributed systems)
• Object-oriented yet high performance
• Pointer and direct memory-access
2
Software Verification [Link]
Introduction to C++ Programming
What is C++?
• A general-purpose programming language that was developed as an
enhancement of the C language to include object-oriented paradigm.
Why learn C++?
• Language for building system software (e.g., operating systems, web
browsers, game engines, database engines, language runtimes and
cloud/distributed systems)
• Object-oriented yet high performance
• Pointer and direct memory-access
• One of the most popular languages and fastest-growing
• [Link]/article/c-is-now-the-fastest-growing-programming-language
• [Link]/article/
most-popular-programming-languages-c-knocks-python-out-of-top-three
2
Software Verification [Link]
Introduction to C++ Programming
• This short introduction does not aim to cover every detailed aspect of C++,
but rather the basic C++ syntax/features in order to develop algorithms to fulfil
the assignment tasks in this subject.
3
Software Verification [Link]
Introduction to C++ Programming
• This short introduction does not aim to cover every detailed aspect of C++,
but rather the basic C++ syntax/features in order to develop algorithms to fulfil
the assignment tasks in this subject.
• You are encouraged to learn and practice more advanced C++
syntax/features.
• [Link]
• [Link]
• Google search ‘C++ programming‘ or ‘introduction to C++ programming‘
3
Software Verification [Link]
Configure Your Integrated Development Environment (IDE)
VSCode + Docker:
[Link]
Installation-of-Docker,-VSCode-and-its-extensions
4
Software Verification [Link]
Write Your First C++ Program
#include <iostream>
using namespace std;
int main() {
cout << "Hello World! \n";
return 0;
}
5
Software Verification [Link]
C++ Primitive Data Types and Variables
6
Software Verification [Link]
C++ Classes and Objects
• C++ class: new data type compared with C for
• Abstraction: ”shows” essential attributes and ”hides” unnecessary information
• Encapsulation: ‘expose‘ only the interfaces and hide implementation details
• A C++ class is a template for objects, and an object is an instance of a class.
7
Software Verification [Link]
C++ Classes and Objects
• C++ class: new data type compared with C for
• Abstraction: ”shows” essential attributes and ”hides” unnecessary information
• Encapsulation: ‘expose‘ only the interfaces and hide implementation details
• A C++ class is a template for objects, and an object is an instance of a class.
#include <iostream>
using namespace std;
class Graph { // the class
private: // private access specifier
int numOfNodes; // hidden attribute from outside
int numOfEdges; // hidden attribute from outside
public: // public access specifier
// interface to outside world
int getNumOfNodes(){ return numOfNodes;}
// interface to outside world
void setNumOfNodes(int n){ numOfNodes = n;}
};
7
Software Verification [Link]
C++ Classes and Objects
• C++ class: new data type compared with C for
• Abstraction: ”shows” essential attributes and ”hides” unnecessary information
• Encapsulation: ‘expose‘ only the interfaces and hide implementation details
• A C++ class is a template for objects, and an object is an instance of a class.
#include <iostream>
using namespace std;
int main() {
class Graph { // the class
// create an object of Graph
private: // private access specifier
Graph graphObj;
int numOfNodes; // hidden attribute from outside
// Access attribute via interface
int numOfEdges; // hidden attribute from outside
[Link](10);
public: // public access specifier
// print out value of the attribute
// interface to outside world
cout << [Link]();
int getNumOfNodes(){ return numOfNodes;}
cout << "\n";
// interface to outside world
}
void setNumOfNodes(int n){ numOfNodes = n;}
};
7
Software Verification [Link]
Constructor
• A constructor is a special method automatically called when an object is
created.
#include <iostream>
using namespace std;
class Graph { // the class
private: // private access specifier
int main() {
int numOfNodes; // hidden attribute from outside
// Create an object via its constructor
int numOfEdges; // hidden attribute from outside
Graph graphObj(5,10);
public: // public access specifier
// print out value of the attribute
Graph(int n, int e){ // constructor
cout << [Link]();
numOfNodes = n;
cout << "\n";
numOfEdges = e;
}
}
// interface to outside world
int getNumOfNodes(){ return numOfNodes;}
};
8
Software Verification [Link]
Containers/Collections
9
Software Verification [Link]
Containers/Collections
#include <vector>
#include <iostream>
using namespace std;
int main ()
{
vector<int> nodeIDs;
nodeIDs.push_back(1);
nodeIDs.push_back(2);
nodeIDs.push_back(2);
// iterating elements via loop
for(auto i : nodeIDs)
cout << i << "\n";
}
10
Software Verification [Link]
Containers/Collections
#include <vector> #include <set>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
int main () int main ()
{ {
vector<int> nodeIDs; set<int> nodeIDs;
nodeIDs.push_back(1); [Link](1);
nodeIDs.push_back(2); [Link](2);
nodeIDs.push_back(2); [Link](2);
// iterating elements via loop // iterating elements via loop
for(auto i : nodeIDs) for(auto i : nodeIDs)
cout << i << "\n"; cout << i << "\n";
} }
10
Software Verification [Link]
Containers/Collections Used in a Class
#include <set>
using namespace std;
class Graph {
private:
int numOfNodes;
int main() {
int numOfEdges;
// Create an object of Graph
set<int> nodeIDs;
Graph graphObj(5,10);
public:
// Increase nodes;
Graph(int n, int e) {
[Link](1);
numOfNodes = n;
[Link](2);
numOfEdges = e;
}
}
void addNode(int id){
[Link](id);
}
};
11
Software Verification [Link]
Pointers for Primitive Types
• The memory address of a variable can be taken through the & operator.
• A pointer however, is a variable that stores the memory address as its value.
int nodeID = 5; // A nodeID variable of type int
int* ptr = &nodeID; // A pointer `ptr` storing the address of nodeID
12
Software Verification [Link]
Pointers for Primitive Types
• The memory address of a variable can be taken through the & operator.
• A pointer however, is a variable that stores the memory address as its value.
int nodeID = 5; // A nodeID variable of type int
int* ptr = &nodeID; // A pointer `ptr` storing the address of nodeID
// Output the value of NodeID (i.e., 5)
cout << nodeID << "\n";
// Output the memory address of NodeID (e.g., 0x6dfed4)
cout << &nodeID << "\n";
// Output the memory address of nodeID with the pointer (e.g., 0x6dfed4)
cout << ptr << "\n";
// Output the value of nodeID via dereferencing the pointer ptr
cout << *ptr << "\n";
13
Software Verification [Link]
References for Primitive Types
ref = 20;
cout << "nodeID = " << nodeID << endl ;
nodeID = 30;
cout << "ref = " << ref << endl ;
14
Software Verification [Link]
References for Primitive Types
15
Software Verification [Link]
C++ const Type Qualifier
• The const keyword allows you to specify whether or not a variable is
modifiable. It can help (1) document your program more clearly and (2)
enable more compiler optimization opportunities.
// a constant integer.
// modifying `nodeID` will get a compilation error.
const int nodeID = 5;
// const Pointer.
// `cptr` is a pointer, which is const, that points to an int.
// modifying `cptr` will get a compilation error
int anotherNodeID = 6;
int* const cptr = &anotherNodeID;
16
Software Verification [Link]
Parameter Passing using Pointers and References
• Both references and pointers can be used to change local variables of one
function inside another function.
/// parameters as values
/// (pass by value)
void swap(int n1, int n2){
int tmp = n1;
n1 = n2;
n2 = tmp;
}
int main(){
int node1 = 2, node2 = 3;
swap(node1, node2);
cout << node1 << " " << node2;
}
17
Software Verification [Link]
Parameter Passing using Pointers and References
• Both references and pointers can be used to change local variables of one
function inside another function.
/// parameters as values
/// (pass by value)
void swap(int n1, int n2){
int tmp = n1;
n1 = n2;
n2 = tmp;
}
int main(){
int node1 = 2, node2 = 3;
swap(node1, node2);
cout << node1 << " " << node2;
}
pass by value: caller and callee have
two independent variables with the
same value (effect not visible to caller)
17
Software Verification [Link]
Parameter Passing using Pointers and References
• Both references and pointers can be used to change local variables of one
function inside another function.
/// parameters as values /// parameters as references
/// (pass by value) /// (Pass by reference)
void swap(int n1, int n2){ void swap(int& n1, int& n2){
int tmp = n1; int tmp = n1;
n1 = n2; n1 = n2;
n2 = tmp; n2 = tmp;
} }
int main(){ int main(){
int node1 = 2, node2 = 3; int node1 = 2, node2 = 3;
swap(node1, node2); swap(node1, node2);
cout << node1 << " " << node2; cout << node1 << " " << node2;
} }
pass by value: caller and callee have
two independent variables with the
same value (effect not visible to caller)
17
Software Verification [Link]
Parameter Passing using Pointers and References
• Both references and pointers can be used to change local variables of one
function inside another function.
/// parameters as values /// parameters as references
/// (pass by value) /// (Pass by reference)
void swap(int n1, int n2){ void swap(int& n1, int& n2){
int tmp = n1; int tmp = n1;
n1 = n2; n1 = n2;
n2 = tmp; n2 = tmp;
} }
int main(){ int main(){
int node1 = 2, node2 = 3; int node1 = 2, node2 = 3;
swap(node1, node2); swap(node1, node2);
cout << node1 << " " << node2; cout << node1 << " " << node2;
} }
pass by value: caller and callee have passed by reference: caller and
two independent variables with the callee share the same variable for the
same value (effect not visible to caller) parameter (effect visible to caller)
17
Software Verification [Link]
Parameter Passing using Pointers and References
• Both references and pointers can be used to change local variables of one
function inside another function.
/// parameters as values /// parameters as references /// parameters as pointers
/// (pass by value) /// (Pass by reference) /// (Pass by pointers)
void swap(int n1, int n2){ void swap(int& n1, int& n2){ void swap(int* n1, int* n2){
int tmp = n1; int tmp = n1; int tmp = *n1;
n1 = n2; n1 = n2; *n1 = *n2;
n2 = tmp; n2 = tmp; *n2 = tmp;
} } }
int main(){ int main(){ int main(){
int node1 = 2, node2 = 3; int node1 = 2, node2 = 3; int node1 = 2, node2 = 3;
swap(node1, node2); swap(node1, node2); swap (&node1, &node2);
cout << node1 << " " << node2; cout << node1 << " " << node2; cout << node1 << " " << node2;
} } }
pass by value: caller and callee have passed by reference: caller and
two independent variables with the callee share the same variable for the
same value (effect not visible to caller) parameter (effect visible to caller)
17
Software Verification [Link]
Parameter Passing using Pointers and References
• Both references and pointers can be used to change local variables of one
function inside another function.
/// parameters as values /// parameters as references /// parameters as pointers
/// (pass by value) /// (Pass by reference) /// (Pass by pointers)
void swap(int n1, int n2){ void swap(int& n1, int& n2){ void swap(int* n1, int* n2){
int tmp = n1; int tmp = n1; int tmp = *n1;
n1 = n2; n1 = n2; *n1 = *n2;
n2 = tmp; n2 = tmp; *n2 = tmp;
} } }
int main(){ int main(){ int main(){
int node1 = 2, node2 = 3; int node1 = 2, node2 = 3; int node1 = 2, node2 = 3;
swap(node1, node2); swap(node1, node2); swap (&node1, &node2);
cout << node1 << " " << node2; cout << node1 << " " << node2; cout << node1 << " " << node2;
} } }
pass by value: caller and callee have passed by reference: caller and pass by pointer: caller and callee
two independent variables with the callee share the same variable for the share the same variable via pointer
same value (effect not visible to caller) parameter (effect visible to caller) dereferences (effect visible to caller)
17
Software Verification [Link]
Parameter Passing using Pointers and References
• Both of them can also be used to save copying of big objects when passed
as arguments to functions or returned from functions, to be more efficient.
class Graph {
public:
int numOfNodes;
int numOfEdges;
};
// If we remove `*` or `&` in below functions, a new copy of the graph object is created.
// `const` used to avoid accidentally updates `g` as the purpose is to print `g` only.
void print(const Graph *g){
cout << g->numOfNodes << " " << g->numOfEdges << " ";
}
void print(const Graph &g){
cout << [Link] << " " << [Link] << " ";
}
18
Software Verification [Link]
Using Pointers in Classes
#include <iostream>
using namespace std;
class Node { // The class
private:
int nodeID; // Node ID
public: // Access specifier
Node(int i){ nodeID = i; } // constructor
int getNodeID() { return nodeID;}
};
class Edge {
private:
Node* src;
Node* dst;
public:
Edge(Node* s,Node* d){ src = s; dst = d; }
Node* getSrc() { return src;}
Node* getDst() { return dst;} ;
};
20
Software Verification [Link]
Putting All the Above Classes Together to Build a Graph
#include <set>
using namespace std; class Edge; class Graph {
class Node { private:
private: set<Node*> nodes; // a set of nodes
int nodeID; public:
set<Edge*> outEdges; // outgoing edges Graph() { }
public: set<Node*>& getNodes(){ return nodes;}
Node(int i){ nodeID = i; } };
int getNodeID() { return nodeID;} int main () {
set<Edge*>& getOutEdges(){ return outEdges;} Node* src = new Node(1);
}; Node* dst = new Node(2);
Edge* edge = new Edge(src, dst);
class Edge { // add src's outgoing edge
private: src->getOutEdges().insert(edge);
Node* src; // create a graph object
Node* dst; Graph* graph = new Graph();
public: // add two nodes into the graph
Edge(Node* s,Node* d){ src = s; dst = d; } graph->getNodes().insert(src);
Node* getSrc() { return src;} graph->getNodes().insert(dst);
Node* getDst() { return dst;} }
};
21
Software Verification [Link]
C++ Inheritance
Allow a child class to inherit attributes and methods from its parent class.
22
Software Verification [Link]
C++ Inheritance
Allow a child class to inherit attributes and methods from its parent class.
class GraphBuilder{
public:
GraphBuilder(){}
void build(){
cout << "parent's way to build..\n";
Node* src = new Node(1);
Node* dst = new Node(2);
Edge* edge = new Edge(src, dst);
// add src's outgoing edge
src->addOutEdge(edge);
// create a graph object
Graph* graph = new Graph();
// add two nodes into the graph
graph->addNode(src);
graph->addNode(dst);
}
};
22
Software Verification [Link]
C++ Inheritance
Allow a child class to inherit attributes and methods from its parent class.
class GraphBuilder{
public:
GraphBuilder(){}
// SubGraphBuilder is a child (derived) class
void build(){ // of GraphBuilder
cout << "parent's way to build..\n"; class SubGraphBuilder : public GraphBuilder{
Node* src = new Node(1); public:
Node* dst = new Node(2); SubGraphBuilder(){}
Edge* edge = new Edge(src, dst); };
// add src's outgoing edge
src->addOutEdge(edge); int main () {
// create a graph object SubGraphBuilder* builder = new SubGraphBuilder();
Graph* graph = new Graph(); // reuse the build method in GraphBuilder
// add two nodes into the graph builder->build();
graph->addNode(src); }
graph->addNode(dst);
}
};
22
Software Verification [Link]
C++ Function Overriding
Allow a child class to override a function (with same signature) in its parent class.
23
Software Verification [Link]
C++ Function Overriding
Allow a child class to override a function (with same signature) in its parent class.
class GraphBuilder{ class SubGraphBuilder : public GraphBuilder{
public: public:
GraphBuilder(){} SubGraphBuilder(){}
// override `build` method in GraphBuilder
void build(){ void build(){
cout << "parent's way to build..\n"; cout << "child's way to build..\n";
Node* src = new Node(1); }
Node* dst = new Node(2); };
Edge* edge = new Edge(src, dst);
// add src's outgoing edge int main () {
src->addOutEdge(edge); SubGraphBuilder* builder1 = new SubGraphBuilder();
// create a graph object // Which `build` method will be called?
Graph* graph = new Graph(); builder1->build();
// add two nodes into the graph
graph->addNode(src); GraphBuilder* builder2 = new SubGraphBuilder();
graph->addNode(dst); // Which `build` method will be called?
} builder2->build();
}; }
23
Software Verification [Link]
C++ Virtual Function and Polymorphism
A function declared with a ‘virtual‘ keyword in a parent class can be overridden by
a child class. When you refer to a child class object using a pointer/reference
to the parent class, it will call child class’s version of this virtual function.
24
Software Verification [Link]
C++ Virtual Function and Polymorphism
A function declared with a ‘virtual‘ keyword in a parent class can be overridden by
a child class. When you refer to a child class object using a pointer/reference
to the parent class, it will call child class’s version of this virtual function.
class GraphBuilder{ class SubGraphBuilder : public GraphBuilder{
public: public:
GraphBuilder(){} SubGraphBuilder(){}
virtual void build(){ void build(){ // override `build` in GraphBuilder
cout << "parent's way to build..\n"; cout << "child's way to build..\n";
Node* src = new Node(1); }
Node* dst = new Node(2); };
Edge* edge = new Edge(src, dst); int main () {
// add src's outgoing edge SubGraphBuilder* builder1 = new SubGraphBuilder();
src->addOutEdge(edge); builder1->build(); // Which `build` will be called?
// create a graph object
Graph* graph = new Graph(); GraphBuilder* builder2 = new SubGraphBuilder();
// add two nodes into the graph builder2->build(); // Which `build` will be called?
graph->addNode(src);
graph->addNode(dst); GraphBuilder* builder3 = new GraphBuilder();
} builder3->build(); // Which `build` will be called?
}; }
24
Software Verification [Link]
Debugging Your C++ Programs
• VSCode ([Link]
• GDB ([Link]
• LLDB ([Link]
• Eclipse CDT ([Link]
• Other tactics, such as printing your results
([Link]
25
Software Verification [Link]
What’s next?
26
Software Verification [Link]