Classes and Dynamic Data

Classes and Dynamic Data - 1

A first attempt at the Date class:

const int MAXLEN = 30;

class Date
{
  public:
    Date(int m, int d, int y, char* msg);
    void Print(void) const;

  private:
    int month;
    int day;
    int year;
    char message[MAXLEN];
};

Date::Date(int m, int d, int y, char* msg)
{
  month = m;
  day = d;
  year = y;

  if (strlen(msg) < MAXLEN)
    strcpy(message, msg);
  else
  {
    strncpy(message, msg, MAXLEN - 1);
    message[MAXLEN - 1] = 0;
  }
}

void Date::Print(void) const
{
  cout << month << "/" << day << "/" << year << " : ";
  cout << message << endl;
}

Classes and Dynamic Data - 2

A second attempt at the Date class:

class Date
{
  public:
    Date(int m, int d, int y, char* msg);
    void Print(void) const;
  
  private:
    int month;
    int day;
    int year;
    char* message;
};

Date::Date(int m, int d, int y, char* msg)
{
  month = m;
  day = d;
  year = y;

  message = new char[strlen(msg) + 1];
  strcpy(message, msg);
}

void Date::Print(void) const
{
  cout << month << "/" << day << "/" << year << " : ";
  cout << message << endl;
}
In this implementation, we dynamically allocate memory for the message array. Notice, however, that we do not provide a mechanism for de-allocating that memory.

Classes and Dynamic Data - 3

A third attempt at the Date class:

class Date
{
  public:

      // constructor
    Date(int m, int d, int y, char* msg);

      // copy-constructor
    Date(const Date& otherDate);

      // deep copy operation
    void CopyFrom(Date otherDate);

      // destructor
    ~Date(void);

    void Print(void) const;

  private:
    int month;
    int day;
    int year;
    char* message;

};
As a rule of thumb: any class that dynamically allocates memory should include a constructor, a destructor, a copy-constructor, and a deep copy operation as public member functions.

Constructors and Destructors

Constructors

Destructors

Destructor for Date class

The destructor for the Date class is trivial:

Date::~Date(void)
{
  delete [] message;
}

Shallow Copy versus Deep Copy

The built-in assignment operator performs a shallow copy of one class object to another; the programmer does not have to write any special code A shallow copy copies only the class members, not any data pointed to by a member A deep copy duplicates both the class members and any data pointed to by a member; the programmer must write code to perform a deep copy (pages 996-997)

date1 = date2;          // shallow copy (built-in)
date1.CopyFrom(date2);  // deep copy (programmer code)

void Date::CopyFrom(Date otherDate)
{
  month = otherDate.month;
  day = otherDate.day;
  year = otherDate.year;
  delete [] message;

  message = new char[strlen(otherDate.message) + 1];
  strcpy(message, otherDate.message);
}

Class Copy-Constructors

Copy constructors are required when initializing one object by another. C++ defines initialization as:

By default, C++ performs these initializations using a shallow copy method. The programmer must implement a copy-constructor to override this default behavior:
void Date::Date(const Date& otherDate)
{
  month = otherDate.month;
  day = otherDate.day;
  year = otherDate.year;

  message = new char[strlen(otherDate.message) + 1];
  strcpy(message, otherDate.message);
}
The constructor does not use any keyword to indicate that it is a copy constructor. The pattern of the parameters is what makes it a copy constructor.
const SomeClass& someObject    // in general
const Date& otherDate          // in our Date class
Allocating Class Objects Dynamically

Until now, all objects have been instantiated implicitly:

void SomeFunction(void)
{
    // construct Date object
  Date date1(4, 15, 1998, "My birthday");
  date1.Print();

}  // date1's destructor is called before function returns
It is possible, and quite common, to explicitly allocate the objects dynamically:
void SomeFunction(void)
{
    // object is created on the free store
  Date* date1 = new Date(4, 15, 1998, "My birthday");
  date1->Print();

    // date1's destructor is called by delete
  delete date1;  
}
Back to Outline