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
datainstead of creating a new copy (shallow copy) - this will cause a memory leak as it overwrites the old pointer
- it will also cause the
chararrays to be shared between differentstringvalinstances, which will complicate memory management.
- Copy constructor - get length of the C-string in
other, setdatato be a new array ofcharof that length, then copy contents ofother.dataintodata
stringval::stringval(const stringval& other)
: len(other.len), data(new char[len]) {
TRACE();
memcpy(data, other.data, len);
}
datastringval::~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
dataandother.dataare 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;
}