Friday 13 April 2012

Exam Reference Book (my notes) Part3





NEW:

Error Handling (new; not in extend details)

Assumption Error – all unknown!
Assume program receives correct input ( e.g. user, file )
Assume function receives correct input (e.g. NULL pter)
Assume function returns correct output (e.g. new operator return NULL coz no memory)
Solution:
Check input once receive è INPUT VALIDATION
Valid – continue
Invalid –
exit(2) ; //terminate program return 2 to OS
cerr << error mssg  //like cout; print error mssg
do other thing
return –1 // error code to caller
–1 is valid integer or error code?
return both error and result  - ( Use reference but messy )
20 parameters and check and return 20 times – messy
constructor cannot return
disturb normal program/function flow

Solution group by one:
#include <cassert>
assert(valid condition)
àif false (TRY): (CATCH)printout assertion failed: invalid condition, line 7, terminated program



Exception

try //referee
{
// Statements that may throw exceptions you want to handle now go here  //flags (exceptions) up if…
throw -1; // throw a literal integer value
throw ENUM_INVALID_INDEX; // throw an enum value
throw "Can not take square root of negative number"; // throw a literal char* string
throw dX; // throw a double variable that was previously defined
throw MyException("Fatal Error"); // Throw an object of class MyException
}
catch (int) //
{
// Any exceptions of type int thrown within the above try block get sent here
cerr << "We caught an exception of type int" << endl;
}
catch (double)
{
// Any exceptions of type double thrown within the above try block get sent here
cerr << "We caught an exception of type double" << endl;
}
Try{
    // Here's all the normal code logic
    m_nFirstParameter = ReadParameter(fSetupIni); //throws exception on failure, jump to enclosing try
    m_nSecondParameter = ReadParameter(fSetupIni);
    m_nThirdParameter = ReadParameter(fSetupIni);
catch (int) // Here's the error handling, nicely separated
    return ERROR_PARAMETER_MISSING; // Some other enum value indicating error
double MySqrt(double dX) {
    // If the user entered a negative number, this is an error condition
    if (dX < 0.0)
        throw "Can not take sqrt of negative number";
// throw exception of type char*
    if (…) throw –1 ;
   return sqrt(dX); }

   int main() {
    cout << "Enter a number: ";
    double dX;
    cin >> dX;
try // Look for exceptions that occur within try block
{
        cout << "The sqrt of " << dX << " is " <<
MySqrt(dX) << endl;
 }
catch (char* strException) // catch exceptions  {
        cerr << "Error: " << strException << endl;
catch(...) {
        cerr << "Abnormal termination" << endl;
If throw, jump to the enclosing try, find the attached catch;
Repeat jump to the next enclosing try, find the attached catch – (unwinding the stack)
Catch’s Char* strException= Throw’s “Cannot take sqrt of negative number”
Continue the remaining code after Catch
- exception handled; unhandled exception error if not found (except use catch all handler catch(…) so that program will not terminated)



Compare to Normal, Route from Throw to Catch and Not terminating are additional :
Normal: Cerr airplane cannot take –1 passengers in function Sqrt, then how about other main call Sqrt?
Exception: pass back to each caller for different Action (Catch) e.g. “airplane cannot take –1 passengers” the function just acts there is error (Throw)
pass back variable which can be used
Normal: terminating by return but I wanna continue the function! 



Exception Class

Try {
int *nValue = new int(anArray[nIndex1] + anArray[nIndex2]);  }
Catch (int nValue)  {
// What are we catching here? From function new? From operator +?? Except using char* (throw “specific error for function1), we can use exception class to describe the problem
class ArrayException
{
private:
std::string m_strError;
ArrayException() {}; // not meant to be called
public:
ArrayException(std::string strError)
: m_strError(strError)
{
}
std::string GetError() { return m_strError; }
}


int IntArray::operator[](const int nIndex)
{
if (nIndex < 0 || nIndex >= GetLength())
throw ArrayException("Invalid index");                         //throw an object (variable) so below use reference
return m_nData[nIndex];
}

try {
    int nValue = anArray[5]; }
catch (ArrayException &cException) {
    cerr << "An array exception occurred (" << cException.GetError() << ")" << endl;
}
//use object.method() to describe the problem instead of char*
throw Derived(); //to map correctly, should avoid Base &cBase= Deriv obj
catch (Derived &cDerived) //correct order
catch (Base &cBase)



Warning for using try catch

Try {
pJohn = new Person("John", 18, E_MALE);  //jumps to catch and didn’t deallocate so that in catch …
catch (PersonException &cException)  {
CloseFile(strFilename);
delete pJohn;
//need to declare pJohn=NULL out of block so that we can access in catch
or
#include <memory> // for std::auto_ptr
auto_ptr<Person> pxJohn(pJohn); // pxJohn now owns pJohn and if jumps to catch, deallocate it (no need to call delete)
//use vector class if pJohn is array
Catch { //unwinding stack – another function catch after throw
~student à throw exception again! //destructor because need to deallocate memory of field
Cerr….
//so handle ~student exception? Or continue cerr <<….? Terminate immediately
As a result, do not throw exception in destructor but good for constructor



Input Validation

Char (letters+int) validation
#include <cctype>
isalnum(int)- casting char
Returns non-zero if the parameter is a letter or a digit
isalpha(int)
Returns non-zero if the parameter is a letter
iscntrl(int)
Returns non-zero if the parameter is a control character
isdigit(int)
Returns non-zero if the parameter is a digit
isgraph(int)
Returns non-zero if the parameter is printable character that is not whitespace
isprint(int)
Returns non-zero if the parameter is printable character (including whitespace)
ispunct(int)
Returns non-zero if the parameter is neither alphanumeric nor whitespace
isspace(int)
Returns non-zero if the parameter is whitespace
isxdigit(int)
Returns non-zero if the parameter is a hexadecimal digit (0-9, a-f, A-F)

bool InputMatches(string strUserInput, string strTemplate) {
    if (strTemplate.length() != strUserInput.length())
        return false;
// Step through the user input to see if it matches
    for (unsigned int nIndex=0; nIndex < strTemplate.length(); nIndex++)
    {
        switch (strTemplate[nIndex])
        {
            case '#': // match a digit
                if (!isdigit(strUserInput[nIndex]))
                    return false;
                break;
            case '_': // match a whitespace
                if (!isspace(strUserInput[nIndex]))
                    return false;
                break;
            case '@': // match a letter
                if (!isalpha(strUserInput[nIndex]))
                    return false;
                break;
            case '?': // match anything
                break;
            default: // match the exact character
                if (strUserInput[nIndex] != strTemplate[nIndex])
                    return false;
        }
    }
return true;

 
int main()
{
    string strValue;
 
    while (1)
    {
        cout << "Enter a phone number (###) ###-####: ";
        getline(cin, strValue); // get the entire line, including spaces
        if (InputMatches(strValue, "(###) ###-####"))
            break;
    }
 
    cout << "You entered: " << strValue << endl;
}




Int (int only) validation
Cin.fail() to ensure it is integer type and no letters; if not, clear() and ignore()















Link List, Queue, Stack implementation

#include <iostream>
using namespace std;

template <class T>
class Stack;

template <class T>
class SNode{
  T _data;
  SNode<T>* _next;
  SNode(T data, SNode<T>* next){
    _data = data;
    _next = next;
  }
  friend class Stack<T>;
};

template <class T>
class Stack{
  SNode<T>* _top;
public:
  Stack();
  void push(T data);
  T pop();
  bool isEmpty()const;
  virtual ~Stack();
};

template <class T>
Stack<T>::Stack(){
 _top = (SNode<T>*)0;
}

template <class T>
void Stack<T>::push(T data){
  SNode<T>* temp = new SNode<T>(data,_top);
  _top = temp;
}



template <class T>
T Stack<T>::pop(){
  T val = _top->_data;
  SNode<T>* toDel = _top;
  _top = _top->_next;
  delete toDel;
  return val;
}

template <class T>
bool Stack<T>::isEmpty()const{
  return !_top;
}


template <class T>
Stack<T>::~Stack(){
  SNode<T>* toDel;
  while(_top){
    toDel = _top;
    _top = _top->_next;
    delete toDel;
  }
}

int main(){
  Stack<int> S;
  int i;
  for(i=100;i<2000;i+=10){
    S.push(i);
  }
  while(!S.isEmpty()){
    cout<<S.pop()<<" ";
  }
  cout<<endl<<"*******************************************"<<endl;
  for(i=100;i<2000;i+=10){
    S.push(i);
  }
  for(i=0;i<10;i++){
    cout<<S.pop()<<" ";
  }
  cout<<endl<<"*******************************************"<<endl;
  return 0;
}
#ifndef __TQUEUE_H__
#define __TQUEUE_H__
/* template signatures:
1- all related classes and types will have the signature
2- the name of the class right after the template will NOT have the signature
3- the constructor names will NOT have the signature
4- the destructor name will NOT have the signature
*/

/* Tqueue requirements:
1- Template class must be copied safely.
2- Template class must work with operator<

*/

template <class type>
class Tqueue;

template <class type>
class Tqnode{
  Tqnode<type>* _next;
  Tqnode<type>* _prev;
  type _data;
  Tqnode(type data,
    Tqnode<type>* prev = (Tqnode<type>*)0,
    Tqnode<type>* next = (Tqnode<type>*)0):_data(data){
    _next = next;
    _prev = prev;
  }
  friend class Tqueue<type>;
};

template <class type>
class Tqueue{
  Tqnode<type>* _head;
  Tqnode<type>* _curr;
  Tqnode<type>* _tail;
public:
  Tqueue(){
    _head = _tail = _curr = (Tqnode<type>*)0;
  }
  virtual ~Tqueue(){
    goHead();
    while(_curr){
      _head = _curr;
      _curr = _curr->_next;
      delete _head;
    }
  }
  bool goNext();
  bool goPrev();
  bool goHead();
  bool goTail();
  bool isEmpty(){
    return !_curr;
  }
  void append(type data){ // appends to tail
    Tqnode<type>* temp= new Tqnode<type>(data, _tail);
    if(_curr){
      _tail = temp;
      _tail->_prev->_next = _tail;
  //    _temp->_prev->_next = _temp;
    }
    else{
      _curr = _head = _tail = temp;
    }
  }
  type remove(){ // removes the data from the head of the list
    if(_head == _tail){
      type data = _head->_data;
      delete _head;
      _head = _tail = _curr = (Tqnode<type>*)0;
      return data;
    }
    else{
      type data = _head->_data;
      Tqnode<type>* todel = _head;
      if(_head == _curr){
        _curr = _curr->_next;
      }
      _head = _head->_next;
      _head->_prev = (Tqnode<type>*)0;
      delete todel;
      return data;
    }
  }
  void insertBefore(type data);  // before current (prev side)
  void insertAfter(type data);  // after current  (next side)
  type visit(){  // returs the data of the current
    return _curr->_data;
  }
  type removeCurrent(); // removes curent
  bool sort(bool Ascending = true);  // sorts the nodes
  void push(type data);
  type pop();

};

template <class type>
bool Tqueue<type>::goTail(){
  bool res = false;
  if(_curr){  // is not null
    _curr = _tail;
    res = true;
  }
  return res;
}

template <class type>
bool Tqueue<type>::goHead(){
  bool res = false;
  if(_curr){  // is not null
    _curr = _head;
    res = true;
  }
  return res;
}

template <class type>
bool Tqueue<type>::goNext(){
  bool res = false;
  if(_curr && _curr->_next){
    _curr = _curr->_next;
    res = true;
  }
  return res;
}

template <class type>
bool Tqueue<type>::goPrev(){
  bool res = false;
  if(_curr != _head){
    _curr = _curr->_prev;
    res = true;
  }
  return res;
}
#endif
#ifndef __TQUEUE_H__
#define __TQUEUE_H__

template <class T>
class Tqueue;

template <class T>
class Tqnode{
  Tqnode<T>* _next;
  Tqnode<T>* _prev;
  T _data;

  Tqnode(T data,
    Tqnode<T>* prev = (Tqnode<T>*)0,
    Tqnode<T>* next = (Tqnode<T>*)0):_data(data){
    _next = next;
    _prev = prev;
  }
  friend class Tqueue<T>;
};

template <class T>
class Tqueue{
  Tqnode<T>* _head;
  Tqnode<T>* _curr;
  Tqnode<T>* _tail;
public:
  Tqueue();
  virtual ~Tqueue();
  bool goNext();
  bool goPrev();
  bool goHead();
  bool goTail();
  bool isEmpty();
  void append(T data);// appends to tail
  T remove(); // removes the data from the head of the list
  void insertBefore(T data);  // before current (prev side)
  void insertAfter(T data);  // after current  (next side)
  T visit(); // returs the data of the current
  T removeCurrent(); // removes curent
  bool sort(bool Ascending = true);  // sorts the nodes
  void push(T data);
  T pop();

};

template <class T>
Tqueue<T>::Tqueue(){
  _head = _tail = _curr = (Tqnode<T>*)0;
}

template <class T>
Tqueue<T>::~Tqueue(){
  goHead();
  while(_curr){
    _head = _curr;
    _curr = _curr->_next;
    delete _head;
  }
}

template <class T>
T Tqueue<T>::visit(){
  return _curr->_data;
}

template <class T>
bool Tqueue<T>::sort(bool Ascending){
  Tqnode<T>* tmp = _curr = _head;
  bool done = false;
  goNext();
  while(tmp && tmp->_next){
    if((Ascending && tmp->_data > _curr->_data) || (!Ascending && tmp->_data < _curr->_data)){
      T buff = tmp->_data;
      tmp->_data = _curr->_data;
      _curr->_data = buff;
    }
    if(!goNext()){
      tmp = tmp->_next;
      if(tmp->_next) _curr = tmp->_next;
      else done = true;
    }
  }
  return done;
}

template <class T>
void Tqueue<T>::append(T data){
  _tail = new Tqnode<T>(data, _tail);
  if(_curr) _tail->_prev->_next = _tail;
  else _curr = _head = _tail;
}

template <class T>
T Tqueue<T>::remove(){
  T data = _head->_data;
  if(_head == _tail){
    delete _head;
    _head = _tail = _curr = (Tqnode<T>*)0;
  }
  else{
    Tqnode<T>* todel = _head;
    if(!_curr->_prev)_curr = _curr->_next;
    _head = _head->_next;
    _head->_prev = (Tqnode<T>*)0;
    delete todel;
  }
  return data;
}

template <class T>
void Tqueue<T>::insertBefore(T data){
  if(_curr){
    _curr = new Tqnode<T>(data, _curr->_prev, _curr);
    _curr->_next->_prev = _curr;
    if(_curr->_prev) _curr->_prev->_next = _curr;
    else _head = _curr;
  }
  else _tail = _head = _curr = new Tqnode<T>(data);
}

template <class T>
void Tqueue<T>::insertAfter(T data){
  if(_curr){
    _curr = new Tqnode<T>(data, _curr, _curr->_next);
    _curr->_prev->_next = _curr;
    if(_curr->_next) _curr->_next->_prev = _curr;
    else _tail = _curr;
  }
  else _tail = _head = _curr = new Tqnode<T>(data);
}

template <class T>
T Tqueue<T>::removeCurrent(){
  T data = _curr->_data;
  if(_curr == _head){
    data = remove();
  }
  else{
    Tqnode<T>* todel = _curr;
    if(_tail == _curr){
      _curr->_prev->_next = (Tqnode<T>*)0;
      _curr = _tail = _curr->_prev;
    }
    else{
      _curr->_prev->_next = _curr->_next;
      _curr->_next->_prev = _curr->_prev;
      _curr = _curr->_next;
    }
    delete todel;
  }
  return data;
}

template <class T>
void Tqueue<T>::push(T data){
  _head = new Tqnode<T>(data, (Tqnode<T>*)0, _head);
  if(_curr) _head->_next->_prev = _head;
  else _curr = _tail = _head;
}

template <class T>
T Tqueue<T>::pop(){
  return remove();
}

template <class T>
bool Tqueue<T>::isEmpty(){
  return !_curr;
}

template <class T>
bool Tqueue<T>::goTail(){
  bool res = false;
  if(_curr){  // is not null
    _curr = _tail;
    res = true;
  }
  return res;
}

template <class T>
bool Tqueue<T>::goHead(){
  bool res = false;
  if(_curr){  // is not null
    _curr = _head;
    res = true;
  }
  return res;
}

template <class T>
bool Tqueue<T>::goNext(){
  bool res = false;
  if(_curr && _curr->_next){
    _curr = _curr->_next;
    res = true;
  }
  return res;
}

template <class T>
bool Tqueue<T>::goPrev(){
  bool res = false;
  if(_curr->_prev){
    _curr = _curr->_prev;
    res = true;
  }
  return res;
}

#endif


















Learn class notes with topics

Jan 12
Namespace
Jan 19
Macros
Jan 23
Default para, function overloading
Jan 26
Array and pointer
Jan 30
Static, class, dynamic memory, ((ostream& const <<))
(Recursion base case), (Boolean while(0))
Feb 2
Pointer to function (ftrp 8?), operator in c, ((virtual))
Feb 6
Reference, (integer size)


Mar 8
Bit operator
Mar 12
Print bits, Template
Mar 15
Template (stack)



Learnc++

Chapter
Finish
Skip
1
1.1-1.9
1.10
2
2.1-2.10

3
3.1-3.9

4
4.1-4.3, 4.5
4.4, 4.6-4.7(typedef, struct)
5

5.1-5.9(control structure)
6
6.1-6.3, 6.5-6.13
6.4 (selection sort)
7
7.1-7.8, 7.11-7.14
7.9-7.10 (stack, recur)
8
8.1,8.10
8.2-8.9, 8.11-8.14
9

9.1-9.12
10
10.1
10.2-10.4(terms)
11
11.1-11.8

12
12.1-12.3
12.4-12.5(bind), 12.6(interfaceclass)
13
13.1-13.2, 13.5-13.7
13.3-13.4(out format, stringclass)
14
14.1-14.5
14.6(partial template)
15
15.1-15.6

16
/
/
17
/
/



project

cout=console

machine code without source file during linkage

so we write console

why extern console??

See cout is object and we can use. It must be created in iostream

So we create extern console (cout) so that we can use the cout.display() to output something on screen!

//object cannot be visualized

//but this project, we draw something out, so we can visualize to difference them~!

//Console holds info, which we can imagine as a screen

//Cframe holds info, which we can imagine as a border

//Cfield holds info, which draw as a frame+data

                //Cbutton holds info, which draw as a frame + holds text

                //Ccheckmark holds info, which draw as a frame + holds 1/0

//Cdialog holds info, which draw as a frame + holds Cfield

*****Cbutton is assign _frame 0 so that it should be fullscreen when draw, but Cdialog add them add() and make cbutton’s _frame to the container so that it is not fullscreen (not draw border) but inside the dialog when draw



Debug for my notes mistake:

*overload type casting means: when u do type casting, it will~ provide class type casting

For Cbutton constructor, we need _data to have string, so we can put string Str to the Cfield constructor and assign it to _data

à problem is _data is void* and str is const char* not just char*

à solution is we cannot assign str to cfield constructor so that we assign it as 0 and then assign _data outside of cfield constructor, define in body

*overload definition It is simply defined as the ability of one function to perform different tasks.

ask prof:
static



Terms:

Relationship of Classes=

1.        Association= Object use another Class’s Methods

2.        Composition= Class inside Class

Encapsulation(classes start)=

1.        hiding (cannot see) Methods logic and Instance data inside class except external appearance

2.        by using separate source file- and the original module which consists of Interface (header file .h file) and Implementation (how it works .c .cpp file which is being compiled) (p.s. C also have this feature tho)


3.        instance data (object field) inside the Class can only be modified by methods inside the Class

4.        by using public and private modifier for Methods and Field inside Class (p.s. C dun have)

Polymorphism=


1.        Language select method of the object’s class which is most appropriate

2.        Identical method

3.        Different method= Different part + identical method

4.         


Language Difference= Concept of Java – Concept of C= Concept of Class and objects (no C but java c++)


Concept’s (where C dun have) feature=Include import, Encapsulation, Inheritance, Polymorphism



------------------------------------------------------------------------------------------------------------------------------------------------



1.        if (student!=NULL) //already allocate dymamic memory to pointer student then delete student

2.        student=NULL;     //to ensure not deleting twice as serious error

3.        student= new (nothrow) Student [n]; // new (nothrow) returns NULL if memory allocation fails; if success like above, allocate additional address will be stored in pointer (student) variable

Memory Issues- Memory Leaks, Insufficient memory

Insufficient Memory=


1.        Solution= use new (nothrow)



OOP344B
2012/04/17
14:00
16:00
T4040
Seneca@York