OOP Class Notes for 11/12/13
Explicit Memory Management in C++: The Law of the Big Three
The Big Three: Copy Constructor, Destructor, and Assignment Operator
The law is: if your class requires a copy constructor, destructor, or assignment operator, it is likely to require all three!
Value Semantics vs. Reference Semantics
- The int type in java uses value semantics.
- Why is that great?
- You can manipulate it without worrying about other variables, very localized
- some languages only have value semantics for this reason
- strings in many programming language have reference semantics
- The program doesn't know the size of the string, so it cannot be allocated to stack
- must be put on heap, thus forced to have references
let's write a C++ class that encapsulates a string with value semantics.
- this code will follow the law of the big three!
- copy constructer is needed to pass stringval instances as parameters in a function
- destructor is needed because it's being stored on the heap - without it the program will not free up memory
- assignment operator is needed to overwrite the default C++
assignment to copy the contents only
- when no operator is defined, it will copy the context of the instance
- so if you make a copy, it will copy the pointer to
data
instead of creating a new copy (shallow copy) - this will cause a memory leak as it overwrites the old pointer
- it will also cause the
char
arrays to be shared between differentstringval
instances, which will complicate memory management.
- Copy constructor - get length of the C-string in
other
, setdata
to be a new array ofchar
of that length, then copy contents ofother.data
intodata
stringval::stringval(const stringval& other) : len(other.len), data(new char[len]) { TRACE(); memcpy(data, other.data, len); }
data
stringval::~stringval() { TRACE(); delete[] data; }
- deallocate the memory for the current C-string before copying
the C-string from
other
- after deleting
data
, you need to reallocate a newchar[]
of appropriate length before copying - No self-assignment! Check to make sure
data
andother.data
are not identical. Otherwise the C-string will be deleted before it is copied.
stringval& stringval::operator=(const stringval& other) { TRACE(); if (data != other.data) { delete[] data; len = other.len; data = new char[len]; memcpy(data, other.data, len); } return *this; }