CS 330 Lecture 32 – Garbage Collection
Agenda
- what ?s
- deconstructors
- garbage collection
- a C++ smart pointer
TODO
- Read section 7.7.3 in your book. Quarter sheet.
- Wondering about Java’s garbage collection? Read http://www.ibm.com/developerworks/library/j-jtp10283/.
- Why do we need both delete and delete[]? Check out http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=287.
Code
FasterString.cpp
#include <cstring>
#include <iostream>
#include "SmartPointer.h"
class FasterString {
public:
FasterString();
FasterString(const char *s);
~FasterString();
int GetLength() const;
char& operator[](int i);
const char& operator[](int i) const;
bool operator==(const FasterString& other) const;
FasterString operator+(const FasterString& other) const;
FasterString operator*(int n) const;
FasterString &operator+=(const FasterString& other);
private:
char *text;
int length;
};
/* ------------------------------------------------------------------------- */
FasterString::FasterString() :
length(0),
text(new char[0]) {
}
/* ------------------------------------------------------------------------- */
FasterString::FasterString(const char *s) :
length(strlen(s)) {
text = new char[length];
memcpy(text, s, sizeof(char) * length);
}
/* ------------------------------------------------------------------------- */
FasterString::~FasterString() {
std::cout << "in dtor" << std::endl;
delete[] text;
}
/* ------------------------------------------------------------------------- */
char& FasterString::operator[](int i) {
return text[i];
}
/* ------------------------------------------------------------------------- */
const char& FasterString::operator[](int i) const {
return text[i];
}
/* ------------------------------------------------------------------------- */
int FasterString::GetLength() const {
return length;
}
/* ------------------------------------------------------------------------- */
std::ostream& operator<<(std::ostream& out, const FasterString &s) {
for (int i = 0; i < s.GetLength(); ++i) {
out << s[i];
}
return out;
}
/* ------------------------------------------------------------------------- */
FasterString FasterString::operator+(const FasterString& other) const {
FasterString joined;
joined.length = GetLength() + other.GetLength();
delete[] joined.text;
joined.text = new char[joined.length];
memcpy(joined.text, text, GetLength());
memcpy(joined.text + GetLength(), other.text, other.GetLength());
return joined;
}
/* ------------------------------------------------------------------------- */
bool FasterString::operator==(const FasterString& other) const {
if (other.GetLength() != GetLength()) {
return false;
}
for (int i = 0; i < GetLength(); ++i) {
if ((*this)[i] != other[i]) {
return false;
}
}
return true;
}
/* ------------------------------------------------------------------------- */
FasterString FasterString::operator*(int n) const {
FasterString joined;
joined.length = GetLength() * n;
delete[] joined.text;
joined.text = new char[joined.length];
for (int i = 0; i < n; ++i) {
memcpy(joined.text + i * GetLength(), text, sizeof(char) * GetLength());
}
return joined;
}
/* ------------------------------------------------------------------------- */
FasterString &FasterString::operator+=(const FasterString& other) {
int new_length = GetLength() + other.GetLength();
char *new_text = new char[new_length];
memcpy(new_text, text, sizeof(char) * GetLength());
memcpy(new_text + GetLength(), other.text, sizeof(char) * other.GetLength());
delete[] text;
text = new_text;
length = new_length;
return *this;
}
/* ------------------------------------------------------------------------- */
int main(int argc, char **argv) {
{
SmartPointer<FasterString> s(new FasterString("Greasy grimy gopher "));
std::cout << "*s: " << *s << std::endl;
/* delete s; */
}
std::cout << "after block" << std::endl;
/* s.Destroy(); */
/* std::cout << "s: " << s << std::endl; */
/* std::cout << "s + FasterString(\"guts\"): " << s + FasterString("guts") << std::endl; */
/* std::cout << "FasterString(\"foo \") * 5: " << FasterString("foo ") * 5 << std::endl; */
/* std::cout << "FasterString(\"a\") + FasterString(\"b\") == FasterString(\"ab\"): " << (FasterString("a") + FasterString("b") == FasterString("ab")) << std::endl; */
/* s += "horns"; */
/* std::cout << "s: " << s << std::endl; */
return 0;
}
SmartPointer.h
#ifndef SMARTPOINTER_H
#define SMARTPOINTER_H
template<typename T> class SmartPointer {
public:
SmartPointer(T *ptr);
SmartPointer(const SmartPointer<T> &other);
~SmartPointer();
SmartPointer<T> &operator=(const SmartPointer<T> &other);
T *operator->();
T &operator*();
private:
void Depatron();
T *ptr;
int *nPatrons;
};
template<typename T>
SmartPointer<T>::SmartPointer(T *ptr) :
ptr(ptr),
nPatrons(new int(1)) {
}
template<typename T>
SmartPointer<T>::SmartPointer(const SmartPointer<T> &other) :
ptr(other.ptr),
nPatrons(other.nPatrons) {
++(*nPatrons);
}
template<typename T>
SmartPointer<T>::~SmartPointer() {
Depatron();
}
template<typename T>
SmartPointer<T> &SmartPointer<T>::operator=(const SmartPointer<T> &other) {
if (&other != this) {
Depatron();
ptr = other.ptr;
nPatrons = other.nPatrons;
++(*nPatrons);
}
return *this;
}
template<typename T>
void SmartPointer<T>::Depatron() {
--(*nPatrons);
if (*nPatrons == 0) {
delete ptr;
ptr = NULL;
delete nPatrons;
nPatrons = NULL;
}
}
template<typename T>
T *SmartPointer<T>::operator->() {
return ptr;
}
template<typename T>
T &SmartPointer<T>::operator*() {
return *ptr;
}
#endif
Haiku
Someday you’ll be gone
Have a non-zero counter
Just one is enough
Have a non-zero counter
Just one is enough