Population

Missionary

    A.First Edition

    This is my first edition of my simple assignment which becomes easier and easier. I complained about this but no

    improvement can be expected.

    B.The problem

    		ASSIGNMENT #5
    		=============

    Create the class hierarchy for email messages.
    The S/W architecture is:

                    Message
                      |
                      |
                     / \
                    /   \
         TextMessage     ImageMessage

    The abstract base class Message is defined as:

    #include <ctime>
    class Message
    {
     public:

      // Constructor and Copy Constructor . . .(implement this yourself)
      // - Should call utility function setTime()

      // Destructor . . .(implement this yourself)

      // Implement any other methods that you will need to use!

      virtual void Display() const = 0;

     private:
      // Utility function to set the member data timeStamp to the system time.
      setTime() { time_t mytime = time(0) ; timeStamp = ctime( &mytime ); }

      char* timeStamp ;	// time stamp string
    };

    A TextMessage publicly inherits from the Message class
    and has a dynamically allocated buffer for its text message:

    char* text;

    An ImageMessage publicly inherits from the Message class
    and has a buffer of characters in which each character is thought
    of as a pixel in an image. The image buffer has 64 characters
    and the size of the image is 8x8.  Its declaration should be:

    char image[64] ;

    Both classes override the Display function.
    The TextMessage version uses cout to output the time stamp and text buffer.
    The ImageMessage version uses cout to output the time stamp and character
    buffer to show the image (see example below) .

    An ImageMessage would be created  and displayed as follows:

    char X[64] ={	' ','X','X','X','X','X','X',' ',
    		'X',' ','X','X','X','X',' ','X',
    		'X','X',' ','X','X',' ','X','X',
    		'X','X','X',' ',' ','X','X','X',
    		'X','X','X',' ',' ','X','X','X',
    		'X','X',' ','X','X',' ','X','X',
    		'X',' ','X','X','X','X',' ','X',
    		' ','X','X','X','X','X','X',' '} ;
    ImageMessage IM( X ) ;
    IM.Display() ;

    The output should look like this:

    Thu Oct 31 17:22:37 2002
     XXXXXX
    X XXXX X
    XX XX XX
    XXX  XXX
    XXX  XXX
    XX XX XX
    X XXXX X
     XXXXXX

    Use a simple main function to demonstrate polymorphism:

     int main() {
         TextMessage t1("this is a test message");
         // You may choose any messages you want
         char C[64] = {	' ','C','C','C','C','C','C',' ',
    			'C','C',' ',' ',' ',' ',' ','C',
    			'C','C',' ',' ',' ',' ',' ',' ',
    			'C','C',' ',' ',' ',' ',' ',' ',
    			'C','C',' ',' ',' ',' ',' ',' ',;
    			'C','C',' ',' ',' ',' ',' ','C',
         			' ','C','C','C','C','C','C',' ',
         			' ',' ',' ',' ',' ',' ',' ',' '  } ;

         ImageMessage I1(C);

         Message* mptr1 = &t1;
         Message* mptr2 = &v1;

         mptr1->Display();
         mptr2->Display();
     }

    The output will look like:

    Thu Oct 31 17:30:15 2002
    this is a test message
    Thu Oct 31 17:30:16 2002
     CCCCCC
    CC     C
    CC
    CC
    CC
    CC     C
     CCCCCC

    NOTE:
    -----
    You are encouraged to add your own functionality to the program and classes.
    This is a good opertunity to practice more operator overloading.

C.The idea of program

    It only test you the concept of virtual functions and abstract class.

    D.The major functions

    ¡¡

    E.Further improvement

    1. You tell me!

    ¡¡

    //file  message.h

    //as everything is done in head file, there is no message.cpp

    #ifndef MESSAGE_H
    #define MESSAGE_H
    #include <ctime>
    class Message
    {
    public:
    	// Constructor and Copy Constructor . . .(implement this yourself)
    	// - Should call utility function setTime()
    	Message(){ setTime();}

    	// Destructor . . .(implement this yourself)
    	virtual ~Message(){;}//in order to call derived class destructor

    	// Implement any other methods that you will need to use!

    	virtual void Display() const = 0;
    protected:
    	//utility method for derived class to access timestamp
    	//however, readonly!
    	const char* getTimeStamp()const { return timeStamp;} //make sure user won't change it.
    private:
    	// Utility function to set the member data timeStamp to the system time.
    	void setTime() { time_t mytime = time(0) ; timeStamp = ctime( &mytime ); }

    	char* timeStamp ;	// time stamp string
    };

    #endif

    ¡¡

    //file TextMessage.h

    #ifndef TEXTMESSAGE_H
    #define TEXTMESSAGE_H

    #include "Message.h"

    class TextMessage: public Message
    {
    public:
    	virtual void Display() const; //re-state it as virtual to help readability
    	TextMessage(const char*);//constructor
    	virtual ~TextMessage();//destructor must be virtual

    private:
    	char* text;
    };

    #endif

    ¡¡

    ¡¡

    //file ImageMessage.h

    #ifndef IMAGEMESSAGE_H
    #define IMAGEMESSAGE_H

    #include "Message.h"

    class ImageMessage: public Message
    {
    public:
    	virtual void Display() const;//re-state as virtual to help readability
    	ImageMessage(const char*);
    	//since there is no dynamic memory allocated,
    	//no constructor is needed
    private:
    	char image[64];
    };

    #endif

    ¡¡

    //ImageMessage.cpp
    #include <iostream>
    #include "ImageMessage.h"

    using namespace std;

    //at least make sure the input str is valid
    ImageMessage::ImageMessage(const char* str)
    {
    	if (str==NULL)
    	{
    		cout<<"Invalid image string!\n";
    	}
    	else
    	{
    		for (int i=0; i<64; i++)
    		{
    			image[i] = str[i];
    		}
    	}
    }

    void ImageMessage::Display() const
    {
    	cout<<getTimeStamp();
    	for (int row=0; row<8; row++)
    	{
    		for (int col=0; col<8; col++)
    		{
    			cout<<image[row*8+col];
    		}
    		cout<<'\n';
    	}
    	cout<<'\n';
    }

    //file TextMessage.cpp

    #include <iostream>
    #include "TextMessage.h"

    using namespace std;

    //implicitly call Message constructor
    TextMessage::TextMessage(const char* str)
    {
    	text = new char[strlen(str)+1];
    	if (text==NULL)
    	{
    		cout<<"Unable to allocate memory for text!\n";
    	}
    	else
    	{
    		strcpy(text, str);
    	}
    }

    void TextMessage::Display() const
    {
    	cout<<getTimeStamp();
    	cout<<text<<endl;
    }

    //as dynamic memory must be deleted, so the destructor of
    //Message class should be virtual so as to call derived class
    //destructor
    TextMessage::~TextMessage()
    {
    	delete [] text;
    }

    ¡¡

    //file Driver.cpp

    #include <iostream>
    #include "Message.h"
    #include "TextMessage.h"
    #include "ImageMessage.h"

    using namespace std;

    int main()
    {
    	 TextMessage t1("this is a test message");
         // You may choose any messages you want
         char C[64] = {	' ','C','C','C','C','C','C',' ',
    			'C','C',' ',' ',' ',' ',' ','C',
    			'C','C',' ',' ',' ',' ',' ',' ',
    			'C','C',' ',' ',' ',' ',' ',' ',
    			'C','C',' ',' ',' ',' ',' ',' ',
    			'C','C',' ',' ',' ',' ',' ','C',
         			 ','C','C','C','C','C','C',' ',
         			' ',' ',' ',' ',' ',' ',' ',' '  } ;

         ImageMessage I1(C);

         Message* mptr1 = &t1;
         Message* mptr2 = &I1;

         mptr1->Display();
         mptr2->Display();

    	return 0;
    }

    ¡¡

    ¡¡

    Running result of program:

    Thu Aug 07 21:28:09 2003
    this is a test message
    Thu Aug 07 21:28:09 2003
     CCCCCC
    CC     C
    CC
    CC
    CC
    CC     C
     CCCCCC

    ¡¡