class

struct and class

All these fields are public, i.e. can be changed by the user.
Because of this, we can’t enforce certain behaviors in structs, like avoiding a negative age.
In class:

  • users can access the public
  • users cannot access the private

define a class

using .h file!

  • .h: define functions
  • .cpp: implement logic
    .h file:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Student {
    private:
    std::string name;
    std::string state;
    int age;
    public:
    /// constructor for our student
    Student(std::string name, std::string state, int age);
    std::string getName();
    std::string getState();
    int getAge();
    }
    .cpp file:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include “Student.h”
    #include <string>
    /// implement constructor
    Student::Student(std::string name, std::string state, int age) {
    this->name = name;
    this->state = state;
    this->age = age;
    }
    std::string Student::getName() {
    return this->name;
    }

    std::string Student::getState() {
    return this->state;
    }

    int Student::getAge() {
    return this->age;
    }
    List initialization constructor(C++11)
    1
    2
    3
    /// implement constructor

    Student::Student(std::string name, std::string state, int age) name{name}, state{state}, age{age} {}
    destructor:
    1
    2
    3
    4
    Student::~Student() {
    /// free/deallocate any data here
    delete [] my_array; /// for illustration
    }
    All containers in STL are classes!

Container adapters

the container that Packaging a larger range of containers into a smaller range of that
![[Pasted image 20240616210816.png]]

Inheritance

like what mentioned in 61B
implementation in C++:
.h file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Shape {
public:
virtual double area() const = 0;
};
class Circle : public Shape {
public:
/// constructor
Circle(double radius): _radius(radius) {};
double area() const {
return 3.14 * _radius * _radius;
}
private:
double _radius;
};

difference between container adapters

  • Subclasses inherit from base class functionality
  • Container adapters provide the interface for several classes and act as a template parameter.

template classes

this

1
2
3
std::string Point::getColor(){
return color;
}

and

1
2
3
std::string Point::getColor(){
return this->color;
}

is the same, but when initializing them?

1
2
3
4
void Point::setX(int x)
{
x = x;
}

will crush!
In the setX function we’re changing the member-variable value of x based on some passed in value.
In getX we’re not modify anything, we’re just getting some value.

implementation of template in C++

template: to make the type a parameter

1
2
3
4
template <typename T>
Container<T>::Container(T val) {
this->value = val;
}

while doing this, you also need to #include "Container.cpp" into the .h file.

const interface

Objects that are const can only interact with the const-interface.
The const interface is simply the functions that are const/do not modify the object/instance of the class.

overall example: IntArray

.h file:

1
2
3
4
5
6
7
8
9
10
class IntArray { 
Private:
int* _array
size_t _size
Public: // constructor
IntArray(size_t size);
~IntArray();
int& at(size_t index);
int size();
}

.cpp file:

1
2
3
4
5
6
7
8
9
10
IntArray::IntArray(size_t size) : _size(size), _array(new int[size]); 
IntArray::~IntArray() {
delete [] _array;
} /// assumes that index is valid
int& at(size_t index) {
return _array[index];
}
int size() {
return this->_size;
}

main:

1
2
3
4
5
6
7
8
9
10
11
12
#include “IntArray.h” 
#include static
void printElement(const IntArray& arr, size_t index) {
std::cout << arr.at(index) << std::endl;
}
int main() {
IntArray arr = IntArray(10);
int& secondVal = arr.at(1); /// actually changes the value of arr at index ‘1’.
secondVal = 19;
printElement(arr, 1);
return 0;
}

problem? const IntArray& arr! our at function didn’t provide ways for const!

1
2
3
int& at(size_t index) const { 
return _array[index];
}

Casting: The process of converting types, there are many ways to do this.
const_cast:
const_cast<target-type> ( expression )
We can use const_cast to cast away const-ness.
So why is this useful

1
2
3
const int& findItem(int value) const { /// one-liners ftw :) 
return const_cast(*this).findItem(value)
}
  1. Cast so that it is pointing to a non-const object
  2. Call the non-const version of the function (this is legal now)
  3. Then cast the non-const return from the function call to a const versio