Lecture15 Slides
Lecture15 Slides
Programming
What do you think makes a good, well-designed
abstraction?
(put your answers the chat)
Object-Oriented
Roadmap Programming
C++ basics
Implementation
User/client
vectors + grids arrays
dynamic memory
stacks + queues
management
sets + maps linked data structures
real-world
Diagnostic algorithms
C++ basics
Implementation
User/client
vectors + grids arrays
dynamic memory
stacks + queues
management
sets + maps linked data structures
real-world
Diagnostic algorithms
● What does my decision tree look like? (decisions, options, what to keep track of)
● What are our base and recursive cases?
● What’s the provided function prototype and requirements? Do we need a helper
function?
● Do we care about returning or keeping track of the path we took to get to our solution?
● Which of our three use cases does our problem fall into? (generate/count all solutions,
find one solution/prove its existence, pick one best solution)
● What are we returning as our solution? (a boolean, a final value, a set of results, etc.)
● What are we building up as our “many possibilities” in order to find our solution?
(subsets, permutations, combinations, or something else)
Where are we now?
classes
object-oriented programming
arrays
arrays
arrays
Definition
abstraction
Design that hides the details of how
something works while still allowing the user
to access complex functionality
What is a class?
Definition
class
A class defines a new data type for our
programs to use.
Definition
class
A class defines a new data type for our
programs to use.
struct Juror {
string name;
int bias;
};
Remember structs?
struct BackpackItem {
int survivalValue; Definition
int weight;
}; struct
A way to bundle different
struct Juror { types of information in C++ –
string name; like creating a custom data
int bias; structure.
};
Then what’s the difference between a class and a struct?
Remember structs?
GridLocation chosen; GPoint origin(0, 0);
cout << chosen.row << endl; cout << origin.getX() << endl;
cout << chosen.col << endl; cout << origin.getY() << endl;
chosen.row = 3; origin.x = 3;
chosen.col = 4; origin.y = 4;
chosen.row = 3; origin.x = 3;
chosen.col = 4; origin.y = 4;
● The only difference between structs + classes are the encapsulation defaults.
○ A struct defaults to public members (accessible outside the class itself).
○ A class defaults to private members (accessible only inside the class
implementation).
Definition
encapsulation
The process of grouping related information
and relevant functions into one unit and
defining where that information is accessible
Another way to think about classes...
● A blueprint for a new type of C++ object!
Another way to think about classes...
● A blueprint for a new type of C++ object!
○ The blueprint describes a general structure, and we can create
specific instances of our class using this structure.
Another way to think about classes...
● A blueprint for a new type of C++ object!
○ The blueprint describes a general structure, and we can create
specific instances of our class using this structure.
Definition
instance
When we create an object that is our new type,
we call this creating an instance of our class.
Another way to think about classes...
● A blueprint for a new type of C++ object!
○ The blueprint describes a general structure, and we can create
specific instances of our class using this structure.
Vector<int> vec;
● Constructor
Three main parts
● Member variables
○ These are the variables stored within the class
○ Usually not accessible outside the class implementation
● Constructor
Three main parts
● Member variables
● Constructor
Three main parts
● Member variables
● Constructor
○ Gets called when you create the object
○ E.g. Vector<int> vec;
Three main parts
● Member variables
○ These are the variables stored within the class
○ Usually not accessible outside the class implementation
● Constructor
○ Gets called when you create the object
○ E.g. Vector<int> vec;
How do we design a class?
We must specify the 3 parts:
● There will be a diagnostic review session hosted by Trip tomorrow night, from
7-8:30pm. The session will be recorded and made available on Canvas shortly
afterwards.
How do we write classes in
C++?
Random Bags
Random Bags
● A random bag is a data structure similar to a stack or queue. It
supports two operations:
○ add, which puts an element into the random bag, and
○ remove random, which returns and removes a random element from the bag.
Random Bags
● A random bag is a data structure similar to a stack or queue. It
supports two operations:
○ add, which puts an element into the random bag, and
○ remove random, which returns and removes a random element from the bag.
● Clients of the class can then include (using the #include directive)
the header file to use the class.
Header files
What's in a header?
What's in a header?
#pragma once
This boilerplate code is called a
preprocessor directive. It’s used to
make sure weird things don’t
happen if you include the same
header twice.
class RandomBag {
class RandomBag {
class RandomBag {
public:
private:
};
The public interface specifies what
What's in a header? functions you can call on objects
of this type.
#pragma once
private:
};
The public interface specifies what
What's in a header? functions you can call on objects
of this type.
#pragma once
private:
Vector<int> elems; Member variable
};
Header summary
#pragma once
#include "vector.h"
class RandomBag {
public:
void add(int value);
int removeRandom();
private:
Vector<int> elems;
};
Implementation files
RandomBag.cpp
#include "RandomBag.h"
#include "RandomBag.h"
If we're going to implement the
RandomBag type, the .cpp file
needs to have the class definition
available. All implementation files
need to include the relevant
headers.
#include "RandomBag.h"
If we're going to implement the
RandomBag type, the .cpp file
needs to have the class definition
available. All implementation files
need to include the relevant
headers.
#pragma once
#include "vector.h"
class RandomBag {
public:
void add(int value);
int removeRandom();
private:
Vector<int> elems;
};
#include "RandomBag.h"
#pragma once
#include "vector.h"
class RandomBag {
public:
void add(int value);
int removeRandom();
private:
Vector<int> elems;
};
#include "RandomBag.h"
#pragma once
#include "vector.h"
class RandomBag {
public:
void add(int value);
int removeRandom();
private:
Vector<int> elems;
};
#include "RandomBag.h"
#pragma once
#include "vector.h"
class RandomBag {
public:
void add(int value);
int removeRandom();
private:
Vector<int> elems;
};
#include "RandomBag.h"
private:
Vector<int> elems;
};
#include "RandomBag.h"
#pragma once
#include "vector.h"
class RandomBag {
public:
void add(int value);
int removeRandom();
private:
Vector<int> elems;
};
#include "RandomBag.h"
int RandomBag::removeRandom() {
if (elems.isEmpty()) {
error("Aaaaahhh!");
}
int index = randomInteger(0, elems.size() - 1);
int result = elems[index];
#pragma once
elems.remove(index);
#include "vector.h"
return result;
class RandomBag {
}
public:
void add(int value);
int removeRandom();
private:
Vector<int> elems;
};
#include "RandomBag.h"
int RandomBag::removeRandom() {
if (elems.isEmpty()) {
error("Aaaaahhh!");
}
int index = randomInteger(0, elems.size() - 1);
int result = elems[index];
#pragma once
elems.remove(index);
#include "vector.h"
return result;
class RandomBag {
}
public:
void add(int value);
int removeRandom();
int size();
bool isEmpty();
private:
Vector<int> elems;
};
#include "RandomBag.h"
int RandomBag::removeRandom() {
if (elems.isEmpty()) {
error("Aaaaahhh!");
}
int index = randomInteger(0, elems.size() - 1);
int result = elems[index];
#pragma once
elems.remove(index);
#include "vector.h"
return result;
class RandomBag {
}
public:
void add(int value);
int RandomBag::size() {
int removeRandom();
return elems.size();
int size();
}
bool isEmpty();
private:
Vector<int> elems;
};
#include "RandomBag.h"
int RandomBag::removeRandom() {
if (elems.isEmpty()) {
error("Aaaaahhh!");
}
int index = randomInteger(0, elems.size() - 1);
int result = elems[index];
#pragma once
elems.remove(index);
#include "vector.h"
return result;
class RandomBag {
}
public:
void add(int value);
int RandomBag::size() {
int removeRandom();
return elems.size();
int size();
}
bool isEmpty();
private:
bool RandomBag::isEmpty() {
Vector<int> elems;
return size() == 0;
};
}
#include "RandomBag.h"
int RandomBag::removeRandom() {
if (elems.isEmpty()) {
error("Aaaaahhh!");
}
int index = randomInteger(0, elems.size() - 1);
int result = elems[index];
#pragma once
elems.remove(index);
#include "vector.h"
return result; This code calls our own class RandomBag {
}
size() function. The class public:
void add(int value);
int RandomBag::size() { implementation can use the int removeRandom();
return elems.size();
} public interface. int size();
bool isEmpty();
private:
bool RandomBag::isEmpty() {
Vector<int> elems;
return size() == 0;
};
}
#include "RandomBag.h"
int RandomBag::removeRandom() {
if (elems.isEmpty()) {
error("Aaaaahhh!"); This use of the const keyword
}
int index = randomInteger(0, size() - 1); means "I promise that this
int result = elems[index]; function doesn't once
#pragma change the
elems.remove(index);
return result; state of#include
the object."
"vector.h"
class RandomBag {
}
public:
void add(int value);
int RandomBag::size() {
int removeRandom();
return elems.size();
int size() const;
}
bool isEmpty() const;
private:
bool RandomBag::isEmpty() {
Vector<int> elems;
return size() == 0;
};
}
#include "RandomBag.h"
int RandomBag::removeRandom() {
if (elems.isEmpty()) {
error("Aaaaahhh!");
}
We have to remember to
int index = randomInteger(0, size() - 1);
int result = elems[index];
add it into the
elems.remove(index);
#pragma once
#include "vector.h"
implementation as well!
return result;
class RandomBag {
}
public:
void add(int value);
int RandomBag::size() const {
int removeRandom();
return elems.size();
int size() const;
}
bool isEmpty() const;
private:
bool RandomBag::isEmpty() const {
Vector<int> elems;
return size() == 0;
};
}
#include "RandomBag.h"
int RandomBag::removeRandom() {
if (elems.isEmpty()) {
error("Aaaaahhh!");
}
int index = randomInteger(0, size() - 1);
int result = elems[index];
#pragma once
elems.remove(index);
#include "vector.h"
return result;
class RandomBag {
}
public:
void add(int value);
int RandomBag::size() const {
int removeRandom();
return elems.size();
int size() const;
}
bool isEmpty() const;
private:
bool RandomBag::isEmpty() const {
Vector<int> elems;
return size() == 0;
};
}
Using a custom class
[Qt Creator demo]
Takeaways
● Public member variables declared in the header file are automatically
accessible in the .cpp file
Takeaways
● Public member variables declared in the header file are automatically
accessible in the .cpp file
● As a best practice, member variables should be private, and you can create
public member functions to allow users to edit them
Takeaways
● Public member variables declared in the header file are automatically
accessible in the .cpp file
● As a best practice, member variables should be private, and you can create
public member functions to allow users to edit them
● Member functions have an implicit parameter that allows them to know what
object they’re operating on
Takeaways
● Public member variables declared in the header file are automatically
accessible in the .cpp file
● As a best practice, member variables should be private, and you can create
public member functions to allow users to edit them
● Member functions have an implicit parameter that allows them to know what
object they’re operating on
● Classes have three main parts to keep in mind when designing them:
○ Member variables → these are always private
○ Member functions (methods)
○ Constructor → this is created by default if you don’t define one
● Writing classes requires the creation of a header (.h) file for the interface and
an implementation (.cpp) file.
What’s next?
Object-Oriented
Roadmap Programming
C++ basics
Implementation
User/client
vectors + grids arrays
dynamic memory
stacks + queues
management
sets + maps linked data structures
real-world
Diagnostic algorithms
C++ basics
Implementation
User/client
vectors + grids arrays
dynamic memory
stacks + queues
management
sets + maps linked data structures
real-world
Diagnostic algorithms