Stack
with constructors & destructors
Reimplementing
the linked list (inside
Stack)
with
constructors and destructors shows up a significant problem. Here’s the
modified header file:
 
//: C06:Stack3.h
// With constructors/destructors
#ifndef STACK3_H
#define STACK3_H
class Stack {
  struct Link {
    void* data;
    Link* next;
    Link(void* dat, Link* nxt);
    ~Link();
  }* head;
public:
  Stack();
  ~Stack();
  void push(void* dat);
  void* peek();
  void* pop();
};Not
only does 
Stack
have a constructor and destructor, but so does the nested class 
Link: 
//: C06:Stack3.cpp {O}
// Constructors/destructors
#include "Stack3.h"
#include "../require.h"
using namespace std;
Stack::Link::Link(void* dat, Link* nxt) {
  data = dat;
  next = nxt;
}
Stack::Link::~Link() {
  delete data;
}
Stack::Stack() { head = 0; }
void Stack::push(void* dat) {
  head = new Link(dat,head);
}
void* Stack::peek() { return head->data; }
void* Stack::pop() {
  if(head == 0) return 0;
  void* result = head->data;
  Link* oldHead = head;
  head = head->next;
  delete oldHead;
  return result;
}
Stack::~Stack() {
  Link* cursor = head;
  while(head) {
    cursor = cursor->next;
    delete head;
    head = cursor;
  }
  head = 0; // Officially emptyThe
Link::Link( )
constructor simply initializes the 
data
and 
next
pointers, so in 
Stack::push( )
the line
 head
= new Link(dat,head);
 not
only allocates a new link (using dynamic object creation with the keyword 
new,
introduced earlier in the book), but it also neatly initializes the pointers
for that link.
 Because
the allocation and cleanup are hidden within 
Stack
– it’s part of the underlying implementation – you
don’t see the effect in the test program:
 
//: C06:Stack3Test.cpp
//{L} Stack3
// Constructors/destructors
#include "Stack3.h"
#include "../require.h"
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char* argv[]) {
  requireArgs(argc, 1); // File name is argument
  ifstream in(argv[1]);
  assure(in, argv[1]);
  Stack textlines;
  string line;
  // Read file and store lines in the stack:
  while(getline(in, line))
    textlines.push(new string(line));
  // Pop the lines from the stack and print them:
  string* s;
  while((s = (string*)textlines.pop()) != 0) {
    cout << s << endl;
    delete s; 
  }The
constructor and destructor for 
textlines
are called automatically, so the user of the class can focus on what to do with
the object and not worry about whether or not it will be properly initialized
and cleaned up.
 
  
	
		
		  Contact: webmaster@codeguru.com
		  
		  CodeGuru - the website for developers.