1/14 Intro

  1. Variables Type: Using classes to fdefin new variable types
  2. Encapsulation:

    • Interface/the API --> .h
    • Implementation --> .cpp (impement methods and initialize variables)
  3. Inclusion Guards:

    • .h : #pragma once (included only once)
    • .cpp: #inlcude "Cube.h"
  4. code examples::

    • Cube::getVolume() means the getVolume() method of class Cube

1/16 Classes

  1. Namespace:

    • Libraries in C++, like packages in Java
    • eg. cs225::Cube; std::out
    • We cannot have two classes with the same name in the same namespace.Discouraged: import everything from a namespace
  2. Constructor:
    2.1 Default Constructor
    2.2 Customized constructors

1/18 Memory

  1. Cube s1 // a variable containing a Cube object
    Cube & s2; // a reference to a variable of type Cube
    Cube * s3; // a pointer to a variable of type Cube
  2. references:

    • eg. int &j = i; // j is an alias of i
    • image.png
    • Once the value of j changes, value of i will also be modified, and vice versa.
  3. pointers:

    • stores a memory address
    • resolve the memory address to access the data
    • eg. std::cout << "Address storing c:" << &c << std::endl;
      std::cout << "Addr. storing ptr: "<< &ptr << std::endl;
    • eg. Cube *p1; p1 = &s1
    • image.png
  4. Indirection Pointers:

    • &c - returns the memory address of c’s data.
    • *ptr - returns the data at the memory address contained at ptr,
    • ptr-> - (*ptr).getVolume() = ptr->getVolume()
  5. Stack Memory:

    • The default type memory
    • Starts near the top of memory (but it does not necessarily start with the mosttop piece memory)
    • Starts at a high address and it grows towards 0
    • The data is read from low to high (the data is read up)
    • All variables are by default on stack (automatic variables)
    • Function sizeof() : return the size of a type in bytes. Int variable takes 4 bytes. Pointer takes 8 bytes
  6. Stack Frame

    • 申明:Each function invocation gets a stack frame.A stack frame is created whenever a function is called.
    • 释放空间:A stack frame is reclaimed when a function returns, and automatically marked free (not actually freed) . When memory is marked free and it can be overwritten. (We never want to return a pointer to the stack variable)

    image.png


1/23 Heap Memory

  1. Heap Memory:

    • the low memory values, grows up (opposite of Stack)
    • 创建:Only create heap memory using keyword new :

      • allocates heap memory
      • calls the object’s constructor
      • returns a pointer to the memory
    • 删除:Only free heap memory using keyword delete :

      • calls the object’s destructor
      • marks memory as free
    • Heap memory is never automatically reclaimed;If we don’t free memory on heap, we are leaking memory, We cannot access it and we cannot reclaim it;When the Heap meets the Stack, we are “out of memory”

image.png

  1. Reference Variable:

    • It never creates new memory, and it needs to be initialized when declared. It can never be redeclared. When we modify the reference variable, that would also modify the variable being aliased.
    • eg. int i = 7; int & j = i;

1/25 Function & Parameter

  1. Arrays:

    • delete [] x;
  2. Three ways to pass an argument to a function:

    • Pass by value:

      • passed in is a copy of the original object and by changing it, we do not change the original.
      • This is safe, but less efficient because it needs extra memory.
      • Cube joinCubes(Cube c1, Cube c2 ){}
      • int main() {
        Cube *c1 = new Cube(4);
        Cube *c2 = new Cube(5);
        Cube c3 = joinCubes( *c1, *c2 );
        return 0;
        }
    • Pass by pointer:

      • Passing a pointer to the original data and by changing the parameter, we are changing the original.
      • This is also more efficient, but more risky. However, here we can also get an invalid parameter (NULL) passed in.
      • Cube joinCubes(Cube * c1, Cube * c2 )
      • int main() {
        Cube *c1 = new Cube(4);
        Cube *c2 = new Cube(5);
        Cube c3 = joinCubes( c1, c2 );
        return 0;
        }
    • Pass by reference:

      • Passing an alias to the variable and by changing the parameter, we are changing the original.
      • This is more efficient, but risky because we are changing the original value.
      • Cube joinCubes(Cube & c1, Cube & c2 )
      • int main() { 
        Cube *c1 = new Cube(4);
        Cube *c2 = new Cube(5);
        Cube c3 = joinCubes( *c1, *c2 );
        return 0;
        }
  3. Const Function Parameter:

    • const is a way to prevent the parameters passed in to be changed.
    • We are saving the memory because we are not passing by value and at the same time to avoid the risk of changing the original.
    • eg. Cube joinCubes( const Cube & c1, const Cube & c2) {}
    • image.png

1/28 Lifecycle

  1. Copy Constructors:

    • Automatic copy constructor. Generated if we do not define a copy constructor. Copy every instance variable in the object
    • Pass by reference

      Cube(const Cube & other){
      ...
      };
  2. Calls to constructors:

    • Copy constructor is called every time when a Cube is copied by value.
    • shallow copy:

      • Tower::Tower(const Tower & other) : cube_(other.cube_),
        ptr_(other.ptr_), ref_(other.ref_) {
        //every variable copied
        //nothing needed in the body
        }
      • image.png
    • Deep copy:

      • Tower::Tower(const Tower & other) : ref_(other.ref_){
        // Deep copy cube_:
        cube_ = other.cube_;
        // Deep copy ptr_
        ptr_ = new Cube(*other.ptr_);
        // Deep copy ref_ (?)
        // Doesn’t make sense to “deep copy” an alias
        // Done in the Initializer List
        }
        
      • ptr_ = new Cube(*other.ptr_);先dereference *other.ptr_获得一个值再放到heap上,ptr_索引上去。
      • image.png
  3. Destructor:

    • cleaning up heap memory and closing all the files. If we ever used new keyword, we have to free the memory (calling delete) so that we don’t leak memory.
    • Automatic Destructor:

      • Stack memory: reclaimed when function returns
      • Heap memory: reclaimed when calling delete
      • Destructor is the final thing to call in the lifecycle of a class.

1/30 Inheritance

  1. Custom destructor:

    • If our member variables are on heap, we need to define a custom destructor.
  2. Overload operators in cpp:

    • Cube.h

      • Cube operator+(const Cube &
        other) const;
        Cube & operator=(const Cube &
        other);
      • ) const --> c3 = c1.operator+(c2)后面的const使LHSc1不变
    • Cube.cpp

      • Cube Cube::operator+(const Cube
        & other) const {
        return joinCube(*this,
        other);
        }
        Cube & Cube::operator=(const
        Cube & other) {
        length_ = other.length_;
        return
  3. Rule of Three:

    • If you define any one of these three functions, you should define ALL of them.

      • ■ Assignment op
      • ■ Copy constructor
      • ■ destructor
    • eg.

      • Cube & Cube::operator=(const Cube & other){
        if (this != &other) { //If I’m not copying
        myself
        _destroy();
        _copy(other);
        }
        return *this;
        };
  4. Inheritance:

    • square.h --> class Square : public Shape {}

      • ■ Everything under Shape public is now in Square public
      • ■ Do not get private variables and functions

2/1 Templates

  1. Virtual:

    • Allow us to override the function in derived classes
    • Evaluate rules:

      • ■ Check the type of the variable
      • ■ Check the matching function in that type. If virtual, go to drive type (the actual instance type)
      • ■ If function not found, check the base type, repeat
    • In a chain of inheritance, every class that was used as a base class need to have its functions virtual
    • eg. image.png
    • image.png
  2. Virtual Destructor:

    • All destructors in base classes must be virtual
    • Destructors will call the base classes destructors
  3. Templates:

    • Template <typename T>

      • we do not need to write same function for various types
      • Template type are checked at compile time
      • eg.

        template <typename T> // 定义T的内涵
        T maximum(T a, T b) {
            T result;
            result = (a > b) ? a : b;
            return result;
        }

2/4 LIST ADT

  1. Linked Memory:

    • image.png
    • A node has two member variables:

      • A list node pointer that points to the next block ListNode * next.
      • The data stored in the block T & data
    • eg.

      #ifndef LIST_H
      #define LIST_H
      template <typename T>
      class List {
       public:
          /* ... */
       private:
       class ListNode {
            T & data;
            ListNode * next;
            ListNode(T & data) : data(data),
            next(NULL) { }
        };
      };
      #endif

References

https://pkgamma.github.io/cs2...


苏打suki
1 声望1 粉丝