C++

Object Oriented Programming in C++

Object Oriented Programming in C++ extends the basic procedural design and programming knowledge into the object oriented paradigm. The student will be expected to learn and apply the basic concepts of object oriented design and programming, i.e. Encapsulation, Abstraction, Inheritance and Polymorphism, in the context of the C++ language.
Course Objectives
On completion of this course you will be able to:
  1. Identify the additional features of C++ compared to c.
  2. Identify and design classes and class hierarchies.
  3. Apply Object Oriented principles of Encapsulation, Abstraction, Inheritance, Polymorphism.
  4. Employ C++ facilities to promote code re-use such as. 
    1. Operator Overloading
    2. Templates
    3. Dynamic binding
  5. Employ C++ I/O facilities including sequential and random access files.
  6. Program using the Standard Template Library.
  7. Employ C++ facilities for Exception handling.                                                           
Course Structure
Topics covered in OOPS using C++ are:
  1. Introduction to C++ and difference between C
  2. Creating Software Objects
  3. Behavior of Software Objects
  4. Inheritance
  5. Multiple Inheritance
  6. Virtual Functions
  7. Friend Functions
  8. Templates
  9. Exceptional Handling
Introduction to CPP                                                                                                                            
Introduction:
Welcome to LexisBirds. You will be introduced to the Origin of C++, the basics of the language and differences between C and C++. You will also learn how to use variables and expressions in C++. These fundamental concepts are the essential building blocks that you will use to create C++ programs throughout the rest of this LexisBirds c++ course.

Origin of C++
Bjarne Stroustrup is the inventor of C++. He began to work on C with Classes in 1979. The idea of creating a new language originated from his experience in programming for his Ph.D. thesis. He found that Simula (another programming language) had features that were very helpful for large software development, but the language was too slow for practical use.
Stroustrup set out to enhance the C language with Simula-like features. C was chosen because it is general-purpose, fast, and portable.
The name C++
This name is credited to Rick Mascitti (mid-1983) and was first used in December 1983. Earlier, during the research period, the developing language had been referred to as "new C", then "C with Classes".
Features of C++
Compared to the C language, C++ introduced extra features, including declarations as statements, function-like casts, new/delete, bool, reference types, inline functions, default arguments, function and operator overloading, namespaces and the scope resolution (::) operator, classes (including all class-related features such as inheritance, member functions, virtual functions, abstract classes, and constructors), templates, exception handling, runtime type identification, and the overloaded input (>>) and output (<<) operators for input and output respectively.
For more information Read
Differences between C and C++
The main difference between C and C++ is that C is a procedure oriented language where as C++ is an object oriented language we can compile and execute all our C programs in a C++ compiler, C++ is an extension to C. C++ was first called 'C with classes' the ++ in C++ indicates the increment operator in C meaning C++ is an advanced language compared to C. The advantage of C++ lies in object oriented programming generally called OOPs. The features of OOPs are Classes, Data Abstraction, Encapsulation, Inheritance, Polymorphism, Exception Handling etc...




Problem Set A:-

  1. Write a simple ‘Hello, new world!’ program in C and CPP edited, compiled and running on your chosen development platform. Change the program to take a command line argument (or multiple command line arguments) and to say ‘Hello name!’
  2. Tabulate all the basic C/C++ types, eg. Char, int, float, double. Don’t forget the unsigned, signed, short, long etc. Write a simple C and C++ program to print out the sizes in bytes of each type on your system.
  3. Find out on your system what the largest and smallest values are for the basic types above? Write a program in C and C++ to print out the Limits of each data type described in previous program.

Problem Set B:-


  1. Write a function to print the date, for the structure Date in C and C++. You need to write the code wherever necessary for the given program in C and C++.
Program to print date in C <source lang=c>
  1. include <stdio.h>//Standard Input and Output Library
struct DATE{
int day;
int month;
int year;
}; void showDate(struct DATE d); void setDate(int d, int m, int year, struct DATE * date); int main(void){
struct DATE date; 
setDate(24,8,2009,&date);
showDate(date); 
return 1;
}
void showDate(struct DATE d){
//Write your code here 
}
void setDate(int d, int m, int y, struct DATE * date){
//Write your code here
} </source>
Program to print date in C++ <source lang="cpp">
  1. include<iostream>//Input/Output stream Library
using namespace std;
struct Date{
int day;
int month;
int year;
void showDate(){
 //Write your code here
}
void setDate(int d, int m, int y){
 //Write your code here
}
};
int main(void){
struct Date date;
date.setDate(24,8,2009);
date.showDate();
system("PAUSE");
return 1;
} </source>
 Resources:
2.Write the struct Date(of previous program) in separate namespace in C++ and use the Date structure in main to print the date.
Problem Set C:-
Write the code in C++ for all the problems given in this problem set.
1. STDIO: Read an integer value N from standard input.
  • Print “LEXISBIRDS BLOGSPOT.IN LET UR IDEAS FLY.. YOUR NAME” for N times using a for-loop.
Resources:
2. STRINGS: use “string” variable
  • Read your firstName
  • Read your lastName
  • Use “+” string operator and contenate firstName and lastName with “_” in between.
  • Display firstName_lastName on the screen
  • Use length() function of string class and display the length of “firstName_lastName”
  • Access the characters in the string “firstName_lastName” and display one by one separated by a single space
  • Ex: Display “Lexis_Birds” as “L e x i s _ B i r d s”
  • Display the characters in reverse order
  • Display as “s d r i B _ s i x e L"
Resources
3. Using new and delete in C++
  1. New and Delete for integer:
  • Read an integer N
  • Create a 1-dimensional dynamic integer array using new[] for N integers
  • Read N integers from the standard input
  • Delete the allocated memory using delete[]
  1. New and Delete for Strings:
  • Read an integer N
  • Create a 1-dimensional dynamic string array using new[] for N strings
  • Read N strings from the standard input
  • Delete the allocated memory using delete[]
  1. New and Delete for 2-dimensional Matrix:
  • Read two integers N and M
  • Create a 2-dimensional dynamic integer array using new[]
  • Read N x M integers from standard input
  • Delete using delete[]
Use separate functions for integer, strings and 2D Matrix.
Resources:
Introduction to OOPs

Introduction

Welcome to the exciting world of Object Oriented Programming! In this module you will be introduced to OOPs concepts and their importance in programming. In the previous module you have done the programs in the same way like which you have done in C programming where there is no Object Oriented Concepts included. CPP is one programming language which supports both Procedural and Object Oriented programming. This module majorly focuses on two most fundamental aspects of OOP that is Object and the Class.
Why do we need OOP?
You may have heard about, or been involved in, horror stories of LMS (Library Management System) project development in structured programming approach. As programs grow larger the project becomes too complex. When more programs are added, complexity increases and disaster ensues. Analyzing the reasons for above problem reveals weaknesses in the procedural paradigm itself. No matter how well structured programming approach is implemented, large problems become excessively complex. The solution to avoid this problem is to practice Object Oriented Approach.

The Object Oriented Approach

The fundamental idea behind object-oriented languages is to combine into a single program entity both data and the functions that operate on that data. Such an entity is called an object. An object’s functions, called member function in C++ because they belong to particular class of objects. In Object Oriented Programming you can’t access the data directly. The data is hidden, so it is safe from accidental alteration. In simple words we can say data and its functions are encapsulated as a single unit. Remember Encapsulation and data hiding are key terms in the description of object oriented languages.
Now let us tell more about objects both in the real world and in terms of programming.

What is an Object

Objects are key to understanding object-oriented technology. Look around right now and you'll find many examples of real-world objects: your dog, your desk, your television set, your bicycle.

State and Behavior of Objects

Real-world objects share two characteristics: They all have state and behavior. Dogs have state (name, color, height, weight…) and behavior (barking, sit, Lay Down, wagging tail…). Bicycles also have state (current gear, current pedal cadence, and current speed) and behavior (changing gear, changing pedal cadence, applying brakes). Identifying the state and behavior of real-world objects is a great way to begin thinking in terms of objects oriented programming.
Take a minute right now to observe the real-world objects that are in your immediate area. For each object that you see, ask yourself two questions: "What possible states can this object be in?" and "What possible behavior can this object perform?" Make sure to write down your observations. As you do, you'll notice that real-world objects vary in complexity; your desktop lamp may have only two possible states (on and off) and two possible behaviors (turn on, turn off) but your desktop radio might have additional states (on, off, current volume, current station) and behavior (turn on, turn off, increase volume, decrease volume, seek, scan, and tune). You may also notice that some objects, in turn, will also contain other objects. These real-world observations all translate into the world of object-oriented programming.

Software Objects

Software objects are conceptually similar to real-world objects: they too consist of state and related behavior. An object stores its state in fields (variables in some programming languages) and exposes its behavior through methods (functions in some programming languages). Methods operate on an object's internal state and serve as the primary mechanism for object-to-object communication. Hiding internal state and requiring all interaction to be performed through an object's methods is known as data encapsulation fundamental principle of object-oriented programming.

Advantages of Software Objects

Bundling code into individual software objects provides a number of advantages, including:
  1. Modularity The source code for an object can be written and maintained independently of the source code for other objects. Once created, an object can be easily passed around inside the system.
  2. Information-hiding By interacting only with an object's methods, the details of its internal implementation remain hidden from the outside world.
  3. Code re-use If an object already exists (perhaps written by another software developer), you can use that object in your program. This allows specialists to implement/test/debug complex, task-specific objects, which you can then trust to run in your own code.
  4. Pluggability and debugging ease if a particular object turns out to be problematic, you can simply remove it from your application and plug in a different object as its replacement. This is analogous to fixing mechanical problems in the real world. If a bolt breaks, you replace it, not the entire machine.

  Resourses:
Walk Through Videos:

 
ObjectOriented Thinking video 1


                                          
ObjectOriented Thinking video 2

Reference Reading
Problem Set A
1. Classes and Objects: Using the following class create an object for it in the main program <source lang=cpp>
 class Integer {
    private:
        int N;
    public:
        void readInteger();
        void printMessage();
 };
void Integer::readInteger() {
     cout<<”enter the value of N”;
      cin>>N;
}
void Integer::printMessage() {
             for (int i = 0 ; i < N ; i++) {
                 cout<<”MSIT @ IIIT Hyderabad and JNTU Hyderabad”<<endl;
             }
 }
</source>
  • Create a object called “intobj” for the class “Integer” in the main program
    • Call intobj.readInteger() and intobj.printMessage() from the main program
    • Add another member function called int addInteger(int no) to the class Integer.
    • The function addInteger() returns the sum of the value of “N + no”.
    • Call intobj.addInteger() from the main program
  • Create a class called "class Circle { };"
    • Add members function to readRadius
    • Add a member function to displayArea
    • Create an object for the class Circle
    • Call the member functions readRadius() and displayArea() from the main program.
2. Create the class called 'Math'. class Math{
 private:
   int ival;
 public: 
    int sum(int x, int y);
};
  • Create a class called “Math”
    • Complete the member function int sum(int x, int y);
    • return the sum of x and y;
    • Write a main program which creates an object say “m” for the class “Math”
    • From the main program read two integers i1, i2.
    • Call the member function “total = m.sum(i1, i2)” to get the sum of i1 + i2
  • Accessing private member in member functions:
    • Modify the member functions so that sum() stores the output in ival.
    • ival = x + y; return ival;
Problem Set B
1. Create a class called State() with the following member functions
  • readDistricts(); //read N = no of districts, dynamically allocated memory for N strings, read each district name from the stdin.
  • printDistricts(); //print the district names on the standard output (display-screen);
  • Use dynamic allocation of strings in the classes is compulsory:
  • Create an object for the class State in the main program
  • Call read_districts() and printDistricts() from the main program
Name the program as: PB1_State.cpp
2. Create class called Interest
  • Create class called Interest with the following attributes and behavior
    • Attributes
    • Principle Amount
    • Number of Years
    • Rate of Interest
  • Behavior
    • readPrincipleAmount();
    • readNoOfYears();
    • readInterestRatePY();
    • calcuateSimpleInterest();
    • calculateCompoundInterest();
  • Create an object for the class Interest in the main program
  • call member functions, read* to read principle amount, no. of years and interest rate
  • call calcuateSimpleInterest() and calculateCompoundInterest() to display the amount+interest separately.

Classes and Objects

Introduction:

Learning Objective

On successful completion of this module you should be able to:

  • Explain the purpose of a class constructor and identify a default constructor for a class
  • Explain the purpose of a class destructor and identify a default destructor for a class
  • Apply function overloading
  • Apply operator overloading
  • Code and use simple C++ classes using the following facilities:
    • public member functions and private data members
    • one or more constructors, including where appropriate, a default constructor
    • Overloading of functions
    • Operator overloading

The Class


In OOP, objects are instances of classes. What does this mean? Let’s look at an analogy. Almost all computer languages have built in data types like int, float, double, char etc… For example we take int. As you know you can declare as many variables of type int as you need in your program. <source lang = cpp> int age; int day; int count; </source>

In addition, class also provides security to the program data; there are three levels of Access Modifiers, which are associated with the class. The members (data or functions) can be declared to be:

  • Private members of the class are hidden and can be accessed only with in the class. Access to them members is denied from outside the class
  • Protected members are accessible within the class and to the derived class(to be covered in next modules)
  • Public members are visible outside the class and can be accessed from anywhere within the program.

A class looks just like a structure, and indeed they are almost equivalent. By convention we always use class for abstract data types and only use structure for ‘ordinary data structures’ that don’t have member functions. The only difference between a structure and a class is that structure members have public access by default and class members have private access by default, you can use the keywords class or struct to define equivalent classes.

The Class Scope


Every class defines the scope for the members in it. The data members of a class may be defined, before they are used in a member functions, or can be used in the member functions, and may be defined later in the class. The data members have the class scope, immaterial of where they are defined in the class.

Resources

Constructor

A constructor is a special member function that has the same name as the class. The constructor will be called automatically whenever an object is created. It could contain initializations to the variables of the object or calling other functions etc. The constructor by nature cannot return any value. The return has to be void. It can however take an argument list. The constructor which takes no arguments is called the default constructor. The constructor can be defined within the class definition or outside of it, just as any other member function definition. It can also be defined outside the class and made inline, just as other member functions.

Copy constructor

A copy constructor is a special constructor in the C++ programming language used to create a new object as a copy of an existing object. First argument of such constructor is a reference to an object of the same type as being constructed (const or non-const), which might be followed by parameters of any type (all having default values). Normally the compiler automatically creates a copy constructor for each class (known as an implicit copy constructor) but for special cases the programmer creates the copy constructor, known as an explicit copy constructor. In such cases, the compiler doesn't create one.

Destructor

The destructor destroys a previously created object. The destructor takes no arguments and cannot return a value. The destructor has the same name as of the class, except that the name is preceded by a ~ (tilda).

Composite Class

A Composite object can be defined as one which consists of other objects. As an example, consider the class Circle as composite object containing an instance of Point, representing the centre and radius which is of type, float. The definition of Point and Circle in this case would be. <source lang="cpp">
class Point{ 
 float x;
 float y;
}; 
class Circle{ 
 float radius;
 Point centre;
}; </source>

Pass by value and Pass by reference

In the parameter passed to the copy constructor, you would notice an ampersand (&). Recall that in C, you can only pass parameters by value and not by reference. C++ enables you to pass parameters by reference. To do so, use an ampersand (&) before the name of the parameter in the parameter declaration.

Function Overloading

One really nice and cool feature in C++ over C is Function Overloading. This means that you can use the same name for different functions. Yes you could. For example, have three functions all named sum(), but each one would have a separate function definitions or return types. It may not seem obvious why you would want to do this, because you may need to sum two or more integers and floating type values in the same program. So these feature so helpful in that case.
Overloading constructor: When constructor is overloaded, the constructor must vary in the argument list. Upon object creation, that constructor for which there is match between the formal and the actual parameters is invoked.

Operator Overloading

You have seen how functions can be overloaded in C++, it also possible to overload the built in C++ operators such as +, -, >=, and ++ so that they could invoke different functions, depending on their operands. For example, the + in a+b will call a function if a and b are integers, but will call different function if a and b are strings or objects of a class you have created. Go through the given urls below to learn more about operator overloading.

The keyword this

The keyword this represents a pointer to the object whose member function is being executed. It is a pointer to the object itself. One of its uses can be to check if a parameter passed to a member function is the object itself.
Resources
Constructors,destructors and functional polymorphism


Problem Set A

1. Define a class Random to provide random numbers within a range that is specified through the constructor. The class should provide a draw function to get a random number. Use the code given below for the Random Class. You need to write the code in the given program wherever it is commented as write the code here
<source lang="cpp">
#include<iostream> //For I/O 
#include <ctime> // For time() 
#include <cstdlib> // For srand() and rand() 
using namespace std; 
class Random{ 
    private:
            int max;
            int min;
    public:
           Random(){ 
                cout << "Default Random Constructor is called and default values set with Min 10 and Max 20\n";            
                   //Write the code here to set the default values for min 10 and max 20 
           }
           Random(int minA, int maxA){
                cout << "Random Constructor called with argument of Min"<< minA << " and Max"<<maxA<<"\n";
                  //Write the code here to set the max and min 
           }
           int draw(){ 
               int r;
               srand(time(0));  // Initialize random number generator.
               r = (rand() % (max - min)) + min;                 
               return r;
           }
}; 
int main(void){ 
//Write the code here to declare two Instances of Random class and by calling different constructors.
//Use cout to call the draw function for each of the Random instance
} 
</source>



Problem Set B

1. Write a class called Point that is capable of representing the coordinates of a point on a two-dimensional graph. You must permit creation of variables as follows: Point p,q(2.1, -4.3); The declaration of p above will be for the point (0,0).
Provide the following operations:
  1. Return the x coordinate or the y coordinate
  2. Set the x coordinate or the y coordinate
  3. Return the distance from the origin, formula is sqrt(x2 + y2)
  4. Input a point as two floating point numbers
  5. Output a point in the format (2.1,-4.3)
Write a short test main function for your class.

Problem Set C

Write a class Point with two public variables x and y. Create a constructor and a copy constructor that display the output “Constructor” and “Copy constructor” respectively followed by a line break (endl). Create a function displayPointByVal, which accepts a Point object by value and a function displayPointByRef, which accepts a Point object by reference. Call displayPointByVal and displayPointByRef in the main function. Indicate, using source code comments, why you observe the difference in output when calling the two functions.
Resources

Polynomial Problem:-
  1. Consider a polynomial with integer coefficients, for instance 5x3 -4 x2 + 5. We can represent this polynomial by array of integers. The 0th element of the array is the coefficient of the x0 term (5 in our example), the 1st element of the array is the coefficient of the x1 term (0 in our example), the 2nd element of the array is the coefficient of the x2 term (-4 in our example), etc. The size of the array determines how large a degree the polynomial can have: a polynomial with degree d will need an array with at least d+ 1 elements. Note that the actual degree of the polynomial may be smaller than (size of vector - 1), since some of the higher order terms may have zero coefficients.
In this problem set, you will implement a Polynomial class. The polynomial class is having two members: array of integers and degree of polynomial as integer. It should support the following member functions.
  1. Int degree() – Return the degree the of the polynomial
  2. Polynomial addition(const Polynomial &p) – Returns the sum q + p, where q is the polynomial object whose member function is called. The degree of this sum will be at most max (degree(q), degree(p)).
  3. Polynomial sub(const Polynomial &p) – Returns the subtraction q - p, where q is the polynomial object whose member function is called. The degree of this subtract will be at most max (degree(q), degree(p)). (Implement it at the end if you have time)
  4. Polynomial multiply(const Polynomial&p) - Returns the product qp, where q is the polynomial object whose member function is called. The degree of this sum will be exactly degree(q) + degree(p). (Implement it at the end if you have time)
  5. bool equal(const Polynomial&p) - Returns true if q is the same polynomial as p, and false otherwise, where q is the polynomial object whose member function is called. Two polynomials are equal if and only if (1) they have the same degree and (2) the coefficient of the terms of the same degree are equal.
  6. void read() - Reads the polynomial from cin. Your code should prompt the user for the degree of the polynomial, create a array with the correct size, and then use a loop to prompt and input each coefficient.
  7. void print() - Outputs the polynomial to cout. The polynomial should be printed out using a format that resembles the following: 5x^3 -4x^2 + 5.
  8. int evaluate(int x) - method to compute and return the polynomial evaluated at x
  9. Additionally, the class should have the following constructors:
    1. Polynomial () - The polynomial is initialized to be a degree 1 polynomial whose only coefficient is zero.
    2. Polynomial (int d) - The polynomial is initialized to be a degree d polynomial. That is, the array should have size d+1 whose coefficients are all zero.
    3. Polynomial (string s) – The polynomial is initialized to the string. (Implement it at the end if you have time)
    4. Polynomial (const Polynomial &p) – The polynomial is initialized to the polynomial passed (Know as copy constructor).
  10. The class should have the following operators overloaded (You are required to overload any 4 operators out of 10)
    1. =
    2. ==
    3. +=
    4. +
    5. -=
    6. *
    7. *=
    8. << (as cout << p)Refer: http://gethelp.devx.com/techtips/cpp_pro/10min/10min0400.asp
    9. >> (as cin >> p) Refer:http://www.csse.monash.edu.au/~jonmc/CSE2305/Topics/10.19.OpOverload/html/text.html#an_important_use_of_operator_overloading
  1. ~Polynomial() - The class should have destructor to delete the memory allocated to the integer array
Write a short test main function for polynomial class with the menu option like
"What would you like to do?"
#Give a value to a polynomial(print the polynomial)
#Add the two polynomials
#Multiply the two polynomials
#Subtract the two polynomials
#Test equality of the two polynomial
#Evaluate the two polynomials for a given value of x
#Quit

Inheritance

 Inheritance

The philosophy behind inheritance is to portray things as they exist in the real world. As inheritance is found in real world, it is important feature of OO programming. Inheritance has many advantages, the most important of them being the reusability of code. Once a class is created, it can be used to create new subclasses. The reuse of existing class saves time and effort.
The Class from which another class is derived is called the base class. The class which inherits the properties of the base class is called the derived class. Each instance of the derived class includes all the members of the base class. Since the derived class inherits all properties of the base class, the derived class has a larger set of properties than its base class. However, the derived class may override some or all the properties of the base class.
In C++, any class can be a base class. More than one class can be derived from a single base class, and a derived class can be a base class to another. if class d1 is inherited from class b1, then the syntax for declaring class derived is
class d1:public b1 
An object defined outside the class can access only the public members of the class. Therefore, private members of a class cannot be directly accessed from outside the class. This holds true even for a derived class. Even though the derived class inherits all the members’ data and functions from the base class, private members of the base class are not directly accessible from the derived class. The idea behind this is never to compromise on encapsulation implemented through data hiding.
The protected members of a class can be accessed by its member’s functions, or within any class derived from it. Protected members behave like public members with respect to the derived class and like private members with respect to the rest of the program.

Overriding Base Class Members

A base class member can be overridden by defining a derived class member with the same name as that of the base class member.
If the function exists in both the derived class and the base class then:
  • If the function is invoked from an Object of the derived class, then the function in the derived class is executed.
  • If the function is invoked from an Object of the base class, then the base class member function is invoked.

Inheritance Example in Real World

In a Banking System, Manager, Officers, Clerk have some common and as well as special behavior (specific tasks/actions). The commonality is that they are all employees of the Bank. A generalized class “Employee_GeneralizedClass” could be used to represent the commonality among Object classes. The generalization is often referred to as inheritance, and the generalized class as parent class. Inheritance is a means of specifying hierarchical relationships between object classes.
Points to Remember
  • The class from which a subclass is derived is referred to as the base class'.
  • Base class constructors and destructors are not inherited by the derived class.
  • Derived class constructors must explicitly call the base class constructors with appropriate parameters.
  • Destructors are invoked in the reverse order.

Resources

Walk Through Video (here)


Inheritance:
Protected:

Problem Set A:-

  1. Draw an inheritance hierarchy for classes QuadrilateralTRapezoidParallelogramRectangle and Square. Use Quadrilateral as the base class of the hierarchy. Make the hierarchy as deep as possible. Example Image for Inheritance is given at: Click here image 
  2. Draw an inheritance hierarchy for classes Shapes. Circle, Square, Triangle and Quadrilateral(described in previous task). Use the Shapes as the base class for the hierarchy. Make the hierarchy as deep as possible.

  1. (Account Inheritance Hierarchy) Create an inheritance hierarchy that a bank might use to represent customers' bank accounts. All customers at this bank can deposit (i.e., credit) money into their accounts and withdraw (i.e., debit) money from their accounts. More specific types of accounts also exist. Savings accounts, for instance, earn interest on the money they hold. Checking accounts, for instance, charge a fee per transaction (i.e., credit or debit). Current accounts, on other hand, has overdraft(Negative balance) facility to withdraw the money.
  2. Create an inheritance hierarchy containing base class Account and derived classes SavingsAccountCheckingAccount andCurrentAccount that inherit from class Account. Base class Account should include one data member of type double to represent the account balance. The class should provide a constructor that receives an initial balance and uses it to initialize the data member. The constructor should validate the initial balance to ensure that it is greater than or equal to 0.0. If not, the balance should be set to 0.0 and the constructor should display an error message, indicating that the initial balance was invalid. The class should provide three member functions. Member function credit should add an amount to the current balance. Member function debit should withdraw money from the Account and ensure that the debit amount does not exceed the Account's balance. If it does, the balance should be left unchanged and the function should print the message "Debit amount exceeded account balance." Member functiongetBalance should return the current balance.
  3. Derived class SavingsAccount should inherit the functionality of an Account, but also include a data member of type double indicating the interest rate (percentage) assigned to the Account. SavingsAccount's constructor should receive the initial balance, as well as an initial value for the SavingsAccount's interest rate. SavingsAccount should provide a public member functioncalculateInterest that returns a double indicating the amount of interest earned by an account. Member function calculateInterestshould determine this amount by multiplying the interest rate by the account balance. [Note: SavingsAccount should inherit member functions credit and debit as is without redefining them.]
  4. Derived class CheckingAccount should inherit from base class Account and include an additional data member of type double that represents the fee charged per transaction. CheckingAccount's constructor should receive the initial balance, as well as a parameter indicating a fee amount. Class CheckingAccount should redefine member functions credit and debit so that they subtract the fee from the account balance whenever either transaction is performed successfully. CheckingAccount's versions of these functions should invoke the base-class Account version to perform the updates to an account balanceCheckingAccount's debit function should charge a fee only if money is actually withdrawn (i.e., the debit amount does not exceed the account balance). [Hint: Define Account's debit function so that it returns a bool indicating whether money was withdrawn. Then use the return value to determine whether a fee should be charged.]
  5. Derived class CurrentAccount should inherit the functionality of an Account, but also include a data member of type double indicating the maximum overdraft limit (percentage) assigned to the Account. CurrentAccount's constructor should receive the initial balance, as well as an initial value for the CurrentAccount's maximum overdraft limit. CurrentAccount should redefine member function debit, so that the account holder can withdraw money upto a maximum of overdraft limit if the balance is below 0. [Note: Anoverdraft occurs when withdrawals from a bank account exceed the available balance which gives the account a negative balance]
  6. After defining the classes in this hierarchy, write a Test program that creates objects of each class and tests their member functions. For Example: Add interest to the SavingsAccount object by first invoking its calculateInterest function, then passing the returned interest amount to the object's credit function.                                                                                                      
Multiple Inheritance

 Multiple Inheritance

Multiple Inheritance is the concept where a subclass inherits properties from multiple base classes. A familiar example of multiple inheritance is the child inheriting the characteristics of the parents. 

In the following example, classes A, B, and C are direct base classes for the derived class X: The following inheritance graph describes the inheritance relationships of the above example. An arrow points to the direct base class of the class at the tail of the arrow: <source lang = cpp> class A { /* ... */ }; class B { /* ... */ }; class C { /* ... */ }; class X : public A, private B, public C { /* ... */ }; </source>


Ambiguities in Multiple Inheritance

When a class inherits from multiple base classes, a whole lot of ambiguities creep in. For example, what happens when two base classes contain a function of the same name?
For example given below --> Class A, Class B has a member function named disp() (to display the attributes of the class) and Class C inherits A and B. <source lang = cpp> class A {
 /* ... */
 public: 
 void disp(void); 
 };
class B {
/* ... */
public:
 void disp(void);
}; class C : public A, private B { /* ... */ }; void main(){
C c;
C.disp();//Ambiguous
} </source> Here the reference to disp() is ambiguous because the compiler does not know whether disp() refers to the member in class base1 or base2. This ambiguity can be resolved using the scope resolution operator as illustrated hereunder. <source lang = cpp> class C : public A, private B { /* ... */ public:
  void disp(void){
     A.disp();
     B.disp();
  } 
}; void main(){
C c;
c.disp();  
} This ambiguity can also be resolved by overriding as illustrated hereunder. void main(){
C c;
c.A::disp();
c.B.::disp();
} </source> Another ambiguity that arises in multiple inheritance is the possibility of the derived class having multiple copies of the same base class. Consider the following diagram. 
<source lang = cpp> class L { /* ... */ }; // indirect base class class B2 : public L { /* ... */ }; class B3 : public L { /* ... */ }; class D : public B2, public B3 { /* ... */ }; // valid </source> In the above example, class D inherits the indirect base class L once through class B2 and once through class B3. However, this may lead to ambiguities because two objects of class L exist, and both are accessible through class D. You can avoid this ambiguity by referring to class L using a qualified class name. For example:
B2::L
or
B3::L
You can also avoid this ambiguity by using the base specifier virtual to declare a base class.

Virtual Base Classes

The principle behind virtual base classes is very simple. When the same class is inherited more than once via multiple paths, multiple copies of the base class members are created in memory. By declaring the base class inheritance as virtual, only one copy of the base class is inherited. A base class inheritance can be specified as virtual using virutal qualifier.
The class definitions would be modified as follows <source lang = cpp> class L { /* ... */ }; // indirect base class class B1 : virtual public L { /* ... */ }; class B2 : virtual public L { /* ... */ }; class D : public B1, public B2 { /* ... */ }; // valid </source> Invocation of Constructors and Destructors
  • Constructors are invoked in the following order:
    • Virtual base class constructors -- in the order of inheritance.
    • Non-Virtual base class constructors -- in the order of inheritance.
    • Member objects constructors -- in the order of declaration
    • Derived class constructor.
  • Destructor are invoked in the reverse order
Resources





Problem Set A:-


  1. Create a set of classes named A, B, C, D, E, F, & G with the following inheritance relationship:
  
Give each class a constructor and destructor only that print simple trace messages to the screen('likeConstructor A or Destructor A ). Use non-virtual inheritance. Test each of the classes individually by creating objects of each type in a Test Program. Study the constructor and destructor trace messages and submit the trace.

Problem Set B:-


  1. Create a set of classes named A, B, C, D, E, F, & G with the following inheritance relationship:

Give each class a constructor and destructor only that print simple trace messages to the screen('likeConstructor A or Destructor A ). Use virtual qualifier in the inheritance wherever necessary. Test each of the classes individually by creating objects of each type in a Test Program. Study the constructor and destructor trace messages and submit the trace.
Problem Set C:-
  1. Thomson publishing company markets both books and video-cassette. Create a class calledPublication that stores the title(string) and price(float) of a publication. From this class derive two classes: Book which adds a page count (type int); and VideoCassette, which adds a playing time(type int) in minutes. Each of these classes should have a getdata() function to get its data from the user and a putdata()function to display its data.
  2. Add another base class Sales that holds an array of three floats so that it can record the sales of a particular publication for the last three months. Include a getdata() function to get three sales amounts from the user, and a putdata() function to display the sales figures. Alter the book and tape classes so that they are derived from both Publication and Sales. An object of class book or tape should input or output sales along with its other data. Write a main() function to create a book object and a tape object and which will update their corresponding member data along with the sales made.

 Polymorphism 

Polymorphism is the ability to associate more than one implementation with the same operation. The binding of the operation with the implementation, can be decided at compile time or at run time. In object orientation, polymorphism can exist in two ways.

  • Hierarchy independent - This takes the form of overloading, where the same name of an operation has different implementations in different classes and these classes need not be related by class hierarchy.
  • Hierarchy dependent- Here, an operation defined in the superclass can have any number of implementations along the class hierarchy. This type of polymorphism is referred to as universal polymorphism or overriding. The operation can be bound to any of the implementations. This resolution can take place, at compile time or at run time.

Pointers


Address and Pointers

The ideas behind pointers are not complicated. Here’s the first key concept: Every byte in the computer’s memory has an address. Addresses are numbers, just as they are for houses on a street. The numbers start at 0 and go up from there —1, 2, 3, and so on. If you have 1MB of memory, the highest address is 1,048,575. (Of course you have much more.)

Your program, when it is loaded into memory, occupies a certain range of these addresses. That means that every variable and every function in your program starts at a particular address.

Pointers to void

Before we go on to see pointers at work, we should note one peculiarity of pointer data types. Ordinarily, the address that you put in a pointer must be the same type as the pointer. You can’t assign the address of a float variable to a pointer to int, for example: float flovar = 98.6; int* ptrint = &flovar; //ERROR: can’t assign float* to int* However, there is an exception to this. There is a sort of general-purpose pointer that can point to any data type. This is called a pointer to void, and is defined like this: void* ptr; //ptr can point to any data type Such pointers have certain specialized uses, such as passing pointers to functions that operate independently of the data type pointed to.
The next example uses a pointer to void and also shows that, if you don’t use void, you must be careful to assign pointers an address of the same type as the pointer. Here’s the listing for PTRVOID:
// ptrvoid.cpp // pointers to type void
include <iostream> using namespace std; int main() {
 int intvar; //integer variable
 float flovar; //float variable
 int* ptrint; //define pointer to int
 float* ptrflo; //define pointer to float
 void* ptrvoid; //define pointer to void
 ptrint = &intvar; //ok, int* to int*
 // ptrint = &flovar; //error, float* to int*
 // ptrflo = &intvar; //error, int* to float*
 ptrflo = &flovar; //ok, float* to float*
 ptrvoid = &intvar; //ok, int* to void*
 ptrvoid = &flovar; //ok, float* to void*
 return 0;
}
You can assign the address of intvar to ptrint because they are both type int*, but you can’t assign the address of flovar to ptrint because the first is type float* and the second is type int*. However, ptrvoid can be given any pointer value, such as int*, because it is a pointer to void.
If for some unusual reason you really need to assign one kind of pointer type to another, you can use the reinterpret_cast. For the lines commented out in PTRVOID, that would look like this:
print = reinterpret_cast<int*>(flovar); ptrflo = reinterpret_cast<float*>(intvar);
The use of reinterpret_cast in this way is not recommended, but occasionally it’s the only way out of a difficult situation. Static casts won’t work with pointers. Old-style C casts can be used, but are always a bad idea in C++.

Base class Pointers

In C++ a pointer of a base class can point to an object of any of its derived class. In the example given below shows what happens when a base class and derived classes all have functions with the same name, and you access these functions using pointers. Here is the listing of BASEPOINT
// basepoint.cpp // normal functions accessed from pointer include <iostream> using namespace std; //////////////////////////////////////////////////////////////// class Base //base class { public:
       void show(){ cout << "Base\n"; }
}; //////////////////////////////////////////////////////////////// class Derv1 : public Base //derived class 1 { public:
       void show(){ cout << "Derv1\n"; }
}; //////////////////////////////////////////////////////////////// class Derv2 : public Base //derived class 2 { public:
       void show(){ cout << "Derv2\n"; }
}; //////////////////////////////////////////////////////////////// int main() { Derv1 dv1; //object of derived class 1 Derv2 dv2; //object of derived class 2 Base* ptr; //pointer to base class
Derv1 *pdv1; //pointer to Derv1 Derv2 *pdv2; //pointer to Derv2
ptr = &dv1; //put address of dv1 in pointer ptr->show(); //execute show() ptr = &dv2; //put address of dv2 in pointer ptr->show(); //execute show()
ptr = &dv1; //put address of dv1 in pointer if(reinterpret_cast<Derv1 *>(ptr) !=0){
 pdv1 =  reinterpret_cast<Derv1 *>(ptr);
 pdv1->show();
} ptr = &dv2; //put address of dv2 in pointer if(reinterpret_cast<Derv2 *>(ptr) !=0){
 pdv2 =  reinterpret_cast<Derv2 *>(ptr);
 pdv2->show();
} return 0; }
Resources

PPT:
References:

Problem Set A:-

  1. Create a set of classes of Shapes (triangle, quadrilateral, circle) with the following inheritance relationship.

Declare and define the classes as
  • Shapes-- Abstract base class.
    • Triangle -- Abstract derived class with base class as Shapes
      • IsoscelesTriangle -- derived class with base class as Triangle.(Attribute with two sides)
      • EquilateralTriangle -- derived class with base class as Triangle(Attribute with one side)
    • Quadrilateral --Abstract derived class with base class as Shapes.
      • Rectangle -- derived class with base class as Quadrilateral.(Attribute with two sides-- length and breadth)
      • Square -- derived class with base class as Quadrilateral.(Attribute with one side)
      • Rhombus -- derived class with base class as Quadrilateral. (Attribute with two sides-- length and breadth)
    • Circle -- Derived class with base class as Shapes. (Attribute with radius)
Use the following declarations for the abstract class and the test main function. Write the code where ever necessary.

#include <iostream>
using namespace std;
////////////////////////////////////////////////////////////////
class Shapes //Abstract base class
{
public:
       virtual double getArea()=0; //Calculates the Area and returns the area
       virtual double getPerimeter()=0; //Calculates the perimeter and return the perimeter.
       virtual void getData()=0; //Take input from the user and store in the state of the object.
       virtual ~Shapes(){};
}; 

class Triangle : public Shapes  //Derived Abstract class
{
//Write your code here
};

class Quadrilateral : public Shapes //Derived Abstract class
{
public:
//Write your code here
};

//Write your code here to declare and define other classes stated

int main(){

//Write your code here to declare an array pointer of Shapes[6].


//Write a Loop for the Menu to create an instance of the object 
// andget the input from the user for the selected Shape 
//and add the pointer to the Shapes array.

//Write a Loop to Print the Area and Perimeter of the array shapes.

    system("PAUSE");        
}

Display a Menu Interface to the user to Create an instance of the Object. The Menu should be like.
  • Create an Instance of
    • Triangle
      • Create IsoscelesTriangle
      • Create EquilateralTriangle
    • Quadrilateral
      • Create Rectangle
      • Create Square
      • Create Rhombus
    • Create Circle

Create should create an instance of the derived class selected and then call the getData() function of that class and store that instance in the array of Shapes(Base Class).
You can add constructors for the derived classes with default values.
Write a test main function to take the input from the user for all the shapes and store them in a array, then print the area and perimeter of the class.

Friend Functions

Friend

The concepts of encapsulation and data hiding dictate that nonmember functions should not be able to access an object’s private or protected data. The policy is, if you’re not a member, you can’t get in. However, there are situations where such rigid discrimination leads to considerable inconvenience. In order to access the non-public members of a class, C++ provides the friend facility. The accessibility of class members in various forms is shown in the below figure 

 

Friend Functions

Imagine that you want a function to operate on objects of two different classes. Perhaps the function will take objects of the two classes as arguments, and operate on their private data. In this situation there’s nothing like a friend function. Here’s a simple example, FRIEND that shows how friend functions can act as a bridge between two classes: <source lang = cpp> / friend.cpp // friend functions include <iostream> using namespace std; class beta; //needed for frifunc declaration //////////////////////////////////////////////////////////////// class alpha { private: int data; public: alpha() : data(3) { }
   //no-arg constructor 
friend int frifunc(alpha, beta); //friend function }; //////////////////////////////////////////////////////////////// class beta { private: int data; public: beta() : data(7) { } //no-arg constructor friend int frifunc(alpha, beta); //friend function }; //////////////////////////////////////////////////////////////// int frifunc(alpha a, beta b) //function definition { return( a.data + b.data ); }; //-------------------------------------------------------------- int main() { alpha aa; beta bb; cout << frifunc(aa, bb) << endl; //call the function return 0; } </source> In this program, the two classes are alpha and beta. The constructors in these classes initialize their single data items to fixed values (3 in alpha and 7 in beta). We want the function frifunc() to have access to both of these private data members, so we make it a friend function. It’s declared with the friend keyword in both classes: friend int frifunc(alpha, beta); This declaration can be placed anywhere in the class; it doesn’t matter whether it goes in the public or the private section. An object of each class is passed as an argument to the function frifunc(), and it accesses the private data member of both classes through these arguments. The function doesn’t do much: It adds the data items and returns the sum. The main() program calls this function and prints the result. A minor point: Remember that a class can’t be referred to until it has been declared. Class beta is referred to in the declaration of the function frifunc() in class alpha, so beta must be declared before alpha. Hence the declaration class beta; at the beginning of the program.

Friend Classes

The member functions of a class can all be made friends at the same time when you make the entire class a friend. The program FRICLASS shows how this looks.
// friclass.cpp 
include <iostream> 
using namespace std; //////////////////////////////////////////////////////////////// 
class alpha { 
 private: int data1; 
 public: alpha() : data1(99) { } //constructor 
 friend class beta; //beta is a friend class 
}; //////////////////////////////////////////////////////////////// 
class beta { //all member functions can access public, private data
 public: 
 private alpha data 
 void func1(alpha a) { cout << “\ndata1=” << a.data1; } 
 void func2(alpha a) { cout << “\ndata1=” << a.data1; } 
}; //////////////////////////////////////////////////////////////// 
int main() { 
 alpha a;
 beta b;
 b.func1(a);
 b.func2(a);
 cout << endl;
 return 0;
} 
In class alpha the entire class beta is proclaimed a friend. Now all the member functions of beta can access the private data of alpha (in this program, the single data item data1). Note that in the friend declaration we specify that beta is a class using the class keyword:
friend class beta; 
We could have also declared beta to be a class before the alpha class specifier, as in previous examples class beta; and then, within alpha, referred to beta without the class keyword:
friend beta; 

Resources


  • Refer previous modules on how to Identify a class, it's state and behavior.

Problem Set A:-

  1. Game Program: The object of tic-tac-toe is to get three X’s or three O’s in a row either horizontally, vertically or diagonally. The tic-tac-toe game board is a 3 x 3 grid and looks something like this:
                                                                                                
         During a typical game, players takes turns placing their X’s and O’s on the game board. The first to get their pattern in a row wins. The follow game board represents what the results of a typical game might look like:                                                                                                                                            

  1.                                                                                                                               Use a 3 x 3 array of cell objects to track player turns. Check the array after each player’s turn to see if they’ve won. Draw the game board on the screen after each turn so players can see the game’s progress. Make it a two player game.
  2. Use Object Oriented Programming approach to solve this problem, thought the problem can be solved simple as presented in the video given.
  3. Write a game program called tic-tac-toe by Identifying the Game as a class consists of Player Objects and Board Object. Board consists of Cell Objects representing the cell in the board.
  4. Identify the Objects in the game with attributes and behavior.
  5. Player can have player Name as an attribute and behavior as playing the game.
  6. Identify and the write friend functions\classes in the board class, cell class, player class and Game class.
  7. Use your imagination to identify the objects, It's not limited to the classes which we have defined.             
Static Polymorphism
Definition of Template                                                                                                                        A template defines a related set of classes or functions. The related set of classes or functions defined by a template share the same code structure and functionality. The class or function template can then be used to declare a new class or function type.
Function Templates
A function template is a generic function declaration and definition from which different versions of the function can be created by the compiler based on the argument types used to call the function. If you think this sound a lot like overloaded functions you are right. Function templates and overloaded functions are related as you will soon see. 
Class Templates 
A class template is a generic class declaration and definition from which different, but related, class types can be created by the compiler based on type parameters.
Structure Templates
A structure template is like a class template but using structures instead.
How Templates Work: An Analogy
When you declare and define a template you are creating a generic version of whatever piece of code you are writing, be it a function or a class. In the declaration and definition of the template you will use one or more identifiers as type placeholders. These type placeholders are similar in function to the placeholders in a form letter generated with a word processor.
The below figure illustrates a simple mail merge operation. A master letter is created with placeholders for certain data elements. The structure of the data source is mapped to the master letter by the placeholder identifiers name and age. When the mail merge function is executed, the data source is merged with the master letter to yield the finished letters. The master letter is a generic document that can be reused to generate many specific letter instances. Class and function templates work in similar fashion. A generic function or class is declared and defined. Placeholders are inserted into the code to reserve spots for actual data types. When specific versions of a template function are required the type substitutions are made based on the types of the arguments used to call the function. In the case of template classes, a special syntax is used when a new template class is declared.

Declaring and Using Function Templates
Up until now, if you wanted to create different versions of the same function to operate on different data types you would overload the function. For instance, if you wanted to declare a function named Sum() that took two arguments, added them together, and returned the result you could create several versions of the function like so:
int Sum(int val1, int val2); 
float Sum(float val1, float val2); 
char Sum(char val1, char val2);
</pree>
These three functions can be replaced with one function template. 
<pre>
ifndef SUM_TEMPLATE_H 
define SUM_TEMPLATE_H 
template<class T> T Sum(T val1, T val2){ 
return val1 + val2;
} 
endif 
The Sum() function is declared to be a template by the keyword template appearing on line 4. Following the keyword template in angle brackets is the keyword class followed by a placeholder identifier named T. The class keyword as it is used here essentially means “any type”. The placeholder T will then appear somewhere in the function. It can appear in more than one place, as it does here in the parameter list. You can use any valid identifier as a placeholder name, not just T. You can also declare more than one placeholder. To use the Sum() function template The Sum() function is called the same way as normal functions are called. The example below shows a main() function using the Sum() function on different data types.
include <iostream> 
ifndef SUM_TEMPLATE_H 
define SUM_TEMPLATE_H 
template<class T> T Sum(T val1, T val2){ 
return val1 + val2;
} 
endif 
using namespace std; 
int main(){ 
cout<<Sum(3, 25)<<endl;//Integer
cout<<Sum(3.456, 5.786)<<endl; //Float
cout<<Sum('a', 'b')<<endl; //Char
//cout<<Sum(3, 3.5)<<endl; return 0; 
} 

Using Multiple Placeholders

The Sum() function template declared and defined in the above example used one type placeholder named T to reserve type spots in the function. Because both of the Sum() function’s parameters are reserved with the same placeholder they must be of the same type when the function is called. To illustrate, let us see what happens when the Sum() function is called with an integer and a float argument as shown in the following line of code:
cout<<Sum(3, 3.5)<<endl; 
Error : in function int main() line no 15: no matching function for call to `Sum(int, double) When the Sum() function template is called with two different argument types an error results. This error was produced using the Dev C++ 4.9.9.2. One way to eliminate this error is to declare the Sum() function template to use two different placeholders.
include <iostream> 
ifndef SUM_TEMPLATE_H 
define SUM_TEMPLATE_H 
template<class T, class U> T Sum(T val1, U val2){ 
 return val1 + val2;
}
endif 
using namespace std; 
int main(){ 
cout<<Sum(3, 25)<<endl;
cout<<Sum(3.456, 5.786)<<endl;
cout<<Sum('a', 'b')<<endl;
cout<<Sum(3, 3.5)<<endl;
return 0;
} 
Notice now there are two type placeholders declared on line 5 of the above example. T and U. The U placeholder is used for the second parameter in the Sum() function while the T placeholder is used for the first parameter and the return value. This will solve one problem but introduce another. The above Example shows the revised Sum() function template in use.
Refer to line 14 of the above example. Notice now that the Sum() function is called with the first argument an integer and the second argument a float. By using two placeholders in the function template the error produced by using two different argument types is eliminated. However, the result type of the Sum() function is dictated by the first argument type. Since the T placeholder is used to reserve the type spot for both the first parameter and the return type of the function, whatever type the first argument to the function happens to be will also be the return type of the function. In this example it is an integer. So, the result of calling the Sum() function with the arguments 3 and 3.5 is 6, not 6.5! Notice what happens when the order of the arguments are swapped.
To resolve the ambiguous return type issue simply declare yet another type place holder used specifically to dictate the function’s return type. The below example gives the revised Sum() function with the extra type placeholder V declared and used to reserve the return type.
include <iostream> 
ifndef SUM_TEMPLATE_H 
define SUM_TEMPLATE_H 
template<class T, class U, class V> V Sum(T val1, U val2){ 
return val1 + val2;
} 
endif 
using namespace std; 
int main(){ 
cout<<Sum<int, int, int>(3, 25)<<endl;
cout<<Sum<double, double, double>(3.456, 5.786)<<endl;
cout<<Sum<char, char, char>('a', 'b')<<endl;
cout<<Sum<double, int, double>(3.5, 3)<<endl;
return 0; }

Declaring And Using Class Templates

Class templates are used to declare and define a generic class structure. The compiler uses the class template and any types supplied via specialization to build a new class type. Let us begin the discussion of class templates with a simple Foo example. Example below shows the declaration and definition of a class template named Foo.
include <iostream> 
ifndef FOOTEMPLATEDEF_H 
define FOOTEMPLATEDEF_H 
template<class T> class Foo{ public: Foo(T _val); virtual ~Foo(); void setVal(T _val); T getVal(); private: T val; }; 
template<class T> Foo<T>::Foo(T _val):val(_val){} 
template<class T> Foo<T>::~Foo(){} 
template<class T> void Foo<T>::setVal(T _val){ val = _val; } 
template<class T> T Foo<T>::getVal(){ return val; } 
endif 
using namespace std; 
int main(){ 
Foo<int> f1(1); 
Foo<char> f2('d'); 
cout<<f1.getVal()<<endl; 
cout<<f2.getVal()<<endl; 
return 0; 
} 
The declaration of the Foo class templates begins on line 6 with the keyword template. There is only one template parameter declared named T. The T is used throughout the class declaration and definition to reserve a spot for the type declared when the Foo class is specialized. Referring to line 33 of above example, notice how the Foo class template is specialized to use an int type. The important point to note in this example is that Foo<int> and Foo<char> are two distinct types. A More Complex Class Template Example The below Example gives the source code for a template of the DynamicArray class.
include <iostream> 
ifndef _DYNAMIC_ARRAY_H 
define _DYNAMIC_ARRAY_H 
template<class T> class DynamicArray{ 
 public: DynamicArray(int _size = 5); 
 virtual ~DynamicArray(); 
 T& operator[](unsigned i); 
 int getSize(); 
 private: T* its_array; 
 int size; 
}; 
//////////////////////////////////////////////////////////
template<class T> DynamicArray<T>::DynamicArray(int _size):size(_size){ 
 its_array = new T[_size]; 
 for(int i=0; i<size; i++) its_array[i] = static_cast<T>(0); 
} 
template<class T> DynamicArray<T>::~DynamicArray(){ 
delete[] its_array; 
} 
template<class T> T& DynamicArray<T>::operator[](unsigned i){ 
 if(i >= (size))
 { 
      int newsize = size+10; 
  T* temp = new T[size]; 
  for(int j = 0; j<size; j++){ 
   temp[j] = its_array[j]; 
  } 
  delete[] its_array; 
  its_array = new T[newsize]; 
  for(int j = 0; j<size; j++){ 
   its_array[j] = temp[j]; 
  }
  for(int j=size; j<newsize; j++){ 
   its_array[j] = static_cast<T>(0); 
  }
  delete[] temp; 
  size = newsize; 
  return its_array[i]; 
 }
 else 
  return its_array[i]; 
} 
template<class T> int DynamicArray<T>::getSize(){ return size;} 
endif 
using namespace std; 
int main(){ 
 DynamicArray<char> d1; 
 DynamicArray<float> d2; 
 for(int i=0; i<6; i++){ 
  d1[i] = 'a'; 
 } 
 for(int i=0; i<6; i++){ 
  d2[i] = (i + .5); 
 } 
 for(int i=0; i<d1.getSize(); i++){ 
  cout<<d1[i]<<" "<<d2[i]<<endl; 
 } return 0; 
} 
Converting the DynamicArray class into a class template increased its usefulness as it can now be used to hold different types of objects, even user-defined types. The above example gives a main() function showing the DynamicArray class template in use.

Resources


PPT:
Header Files:
Problem Set A:-
  1. Create a function called swaps() that interchanges the values of the two arguments sent to it. (You will probably want to pass these arguments by reference.) Make the function into a template, so it can be used with all numerical data types (char, int, float, and so on). Write a main() program to exercise the function with several types.

Problem Set B:-

  1. Create a function called amax() that returns the value of the largest element in an array. The arguments to the function should be the address of the array and its size. Make this function into a template so it will work with an array of any numerical type. Write a main() program that applies this function to arrays of various types.

Problem Set C:-

  • A queue is a data-storage device. It’s like a stack, except that, instead of being last-in first-out, it’s first-in-first-out, like the line at a bank teller’s window. If you put in 1, 2, 3,you get back 1, 2, 3 in that order.
  • A stack needs only one index to an array (i.e top of the array). A queue, on the other hand, must keep track of two indexes to an array: one to the tail, where new items are added, and one to the head, where old items are removed. The tail follows the head through the array as items are added and removed. If either the tail or the head reaches the end of the array, it is reset to the beginning.
  1. Write a class template for a queue class. Assume that the programmer using the queue won’t make any mistakes, like exceeding the capacity of the queue or trying to remove an item when the queue is empty. Define several queues of different data types and insert and remove data from them.                                                                                          Use the dynamicarray discussed previously for implementing the queue.                     Write the declaration and defining of Queue template in separate header file and a Test program to test the queue in separate source file.
Refer:

Why do we need exceptions?


Why do we need a new mechanism to handle errors? Let’s look at how the process was handled in the past. C-language programs often signal an error by returning a particular value from the function in which it occurred. For example, disk-file functions often return NULL or 0 to signal an error. Each time you call one of these functions you check the return value:

if( somefunc() == ERROR_RETURN_VALUE ) 
//handle the error or call error-handler function 
else 
//proceed normally 
if( anotherfunc() == NULL ) 
//handle the error or call error-handler function 
else 
//proceed normally 
if( thirdfunc() == 0 ) //handle the error or call error-handler function 
else 
//proceed normally 

The Problem with this approach is that every single call to such a function must be examined by the program. Surrounding each function call with an if...else statement, and adding statements to handle the error (or call an error-handler routine), requires a lot of code and makes the listing convoluted and hard to read.

Exception Syntax


Imagine an application that creates and interacts with objects of a certain class. Ordinarily the application’s calls to the class member functions cause no problems. Sometimes, however, the application makes a mistake, causing an error to be detected in a member function. This member function then informs the application that an error has occurred. When exceptions are used, this is called throwing an exception. In the application we install a separate section of code to handle the error. This code is called an exception handler or catch block; it catches the exceptions thrown by the member function. Any code in the application that uses objects of the class is enclosed in a try block. Errors generated in the try block will be caught in the catch block. Code that doesn’t interact with the class need not be in a try block. Below image shows the arrangement.

The exception mechanism uses three new C++ keywords: throw, catch, and try. Also, we need to create a new kind of entity called an exception class. XSYNTAX is not a working program, but a skeleton program to show the syntax.
// xsyntax.cpp
// not a working program
////////////////////////////////////////////////////////////////
class AClass //a class
{
public:
 class AnError //exception class
 {
 };
 
 void Func() //a member function
 {
  if( /* error condition */ )
  throw AnError(); //throw exception
 }
};
 
////////////////////////////////////////////////////////////////
 
int main() //application
{
 try //try block
 {
  AClass obj1; //interact with AClass objects
  obj1.Func(); //may cause error
 }
 catch(AClass::AnError)  //exception handler
 {    //(catch block)
  //tell user about error, etc.
 }
return 0;
}
We start with a class called AClass, which represents any class in which errors might occur. An exception class, AnError, is specified in the public part of AClass. In AClass’s member functions we check for errors. If we find one, we throw an exception, using the keyword throw followed by the constructor for the error class:
throw AnError(); //’throw’ followed by constructor for AnError class
In the main() part of the program we enclose any statements that interact with AClass in a try block. If any of these statements causes an error to be detected in an AClass member function, an exception will be thrown and control will go to the catch block that immediately follows the try block.

A simple Exception Example

Let’s look at a working program example that uses exceptions. This example creates a stack data structure in which integer data values could be stored. The application program might attempt to push too many objects onto the stack, thus exceeding the capacity of the array, or it might try to pop too many objects off the stack, thus obtaining invalid data. In the XSTAK program we use an exception to handle these two errors.
// xstak.cpp
// demonstrates exceptions
#include <iostream>
using namespace std;
const int MAX = 3; //stack holds 3 integers
////////////////////////////////////////////////////////////////
class Stack
{
private:
 int st[MAX]; //array of integers
 
 int top; //index of top of stack
public:
 class Range //exception class for Stack
 { //note: empty class body
 };
 
 Stack() //constructor
 { top = -1; }
 
 void push(int var)
 {
  if(top >= MAX-1) //if stack full,
  throw Range(); //throw exception
  st[++top] = var; //put number on stack
 }
 
 int pop()
 {
  if(top < 0) //if stack empty,
  throw Range(); //throw exception
  return st[top--]; //take number off stack
 }
};
////////////////////////////////////////////////////////////////
 
int main()
{
 Stack s1;
 try
 {
  s1.push(11);
  s1.push(22);
  s1.push(33);
  // s1.push(44); //oops: stack full
  cout << “1: “ << s1.pop() << endl;
  cout << “2: “ << s1.pop() << endl;
  cout << “3: “ << s1.pop() << endl;
  cout << “4: “ << s1.pop() << endl; //oops: stack empty
 }
 catch(Stack::Range) //exception handler
 {
  cout << “Exception: Stack Full or Empty” << endl;
 }
  cout << “Arrive here after catch (or normal exit)” << endl;
 return 0;
}
Note that we’ve made the stack small so that it’s easier to trigger an exception by pushing too many items. Let’s examine the features of this program that deal with exceptions. There are four of them. In the class specification there is an exception class. There are also statements that throw exceptions. In the main() part of the program there is a block of code that may cause exceptions (the try block), and a block of code that handles the exception (the catch block). Specifying the Exception Class The program first specifies an exception class within the Stack class:
class Range{ 
//note: empty class body
};
Here the body of the class is empty, so objects of this class have no data and no member functions. All we really need in this simple example is the class name, Range. This name is used to connect a throw statement with a catch block. (The class body need not always be empty, as we’ll see later.)

Throwing an Exception

In the Stack class an exception occurs if the application tries to pop a value when the stack is empty or tries to push a value when the stack is full. To let the application know that it has made such a mistake when manipulating a Stack object, the member functions of the Stack class check for these conditions using if statements, and throw an exception if they occur. In XSTAK the exception is thrown in two places, both using the statement
throw Range();
The Range() part of this statement invokes the implicit constructor for the Range class, which creates an object of this class. The throw part of the statement transfers program control to the exception handler (which we’ll examine in a moment).

The try Block

All the statements in main() that might cause this exception—that is, statements that manipulate Stack objects—are enclosed in braces and preceded by the try keyword:
try
{
//code that operates on objects that might cause an exception
}
This is simply part of the application’s normal code; it’s what you would need to write even if you weren’t using exceptions. Not all the code in the program needs to be in a try block; just the code that interacts with the Stack class. Also, there can be many try blocks in your program, so you can access Stack objects from different places.

The Exception Handler (Catch Block)

The code that handles the exception is enclosed in braces, preceded by the catch keyword, with the exception class name in parentheses. The exception class name must include the class in which it is located. Here it’s
Stack::Range
catch(Stack::Range)
{
 //code that handles the exception
}
This construction is called the exception handler. It must immediately follow the try block. In XSTAK the exception handler simply prints an error message to let the user know why the program failed.
Control “falls through” the bottom of the exception handler, so you can continue processing at that point. Or the exception handler may transfer control elsewhere, or (often) terminate the program.
Sequence of Events Let’s summarize the sequence of events when an exception occurs:
  • Code is executing normally outside a try block.
  • Control enters the try block.
  • A statement in the try block causes an error in a member function.
  • The member function throws an exception.
  • Control transfers to the exception handler (catch block) following the try block.
That’s all there is to it. Notice how clean the resulting code is. Any of the statements in the try block could cause an exception, but we don’t need to worry about checking a return value for each one, because the try-throw-catch arrangement handles them all automatically. In this particular example we’ve deliberately created two statements that cause exceptions. The first s1.push(44); //pushes too many items Causes an exception if you remove the comment symbol preceding it, and the second
cout << “4: “ << s1.pop() << endl; //pops item from empty stack
Causes an exception if the first statement is commented out, try it each way. In both cases the same error message will be displayed: Stack Full or Empty

Multiple Exceptions

You can design a class to throw as many exceptions as you want. To show how this works, we’ll modify the XSTAK program to throw separate exceptions for attempting to push data on a full stack and attempting to pop data from an empty stack. Here’s the listing for XSTAK2:
// xstak2.cpp
// demonstrates two exception handlers
#include <iostream>
using namespace std;
const int MAX = 3; //stack holds 3 integers
////////////////////////////////////////////////////////////////
class Stack
{
private:
 int st[MAX]; //stack: array of integers
 int top; //index of top of stack
public:
 class Full { }; //exception class
 
 class Empty { }; //exception class
 
//--------------------------------------------------------------
 Stack() //constructor
 { top = -1; }
//--------------------------------------------------------------
 void push(int var) //put number on stack
 {
  if(top >= MAX-1) //if stack full,
   throw Full(); //throw Full exception
  st[++top] = var;
}
 
//--------------------------------------------------------------
 int pop() //take number off stack
 {
  if(top < 0) //if stack empty,
   throw Empty(); //throw Empty exception
 return st[top--];
 }
};
////////////////////////////////////////////////////////////////
int main()
{
 Stack s1;
 try
 {
  s1.push(11);
  s1.push(22);
  s1.push(33);
  // s1.push(44); //oops: stack full
  cout << “1: “ << s1.pop() << endl;
  cout << “2: “ << s1.pop() << endl;
  cout << “3: “ << s1.pop() << endl;
  cout << “4: “ << s1.pop() << endl; //oops: stack empty
 }
 catch(Stack::Full)
 {
  cout << “Exception: Stack Full” << endl;
 }
 catch(Stack::Empty)
 {
  cout << “Exception: Stack Empty” << endl;
 }
 return 0;
}
In XSTAK2 we specify two exception classes:
class Full { };
class Empty { };
The statement
throw Full();
Is executed if the application calls push() when the stack is already full, and 
throw Empty();
Is executed if pop() is called when the stack is empty. 
A separate catch block is used for each exception: 
try
{
//code that operates on Stack objects
}
catch(Stack::Full)
{
//code to handle Full exception
}
catch(Stack::Empty)
{
//code to handle Empty exception
}
All the catch blocks used with a particular try block must immediately follow the try block. In this case each catch block simply prints a message: “Stack Full” or “Stack Empty”. Only one catch block is activated for a given exception. A group of catch blocks, or a catch ladder, operates a little like a switch statement, with only the appropriate section of code being executed. When an exception has been handled, control passes to the statement following all the catch blocks. (Unlike a switch statement, you don’t need to end each catch block with a break. In this way catch blocks act more like functions.)

Specifing Data in an Exception Class

What happens if the application needs more information about what caused an exception? For instance, in the XSTAK2 example, it might help the programmer to know what MAX elements the stack can have.
It’s convenient to make the data in an exception class public so it can be accessed directly by the exception handler. Here’s the specification for the new Full exception class in XSTAK2:
class Full{ //exception class
 public:
  int maxElements; //Max elements the stack can store
  string message; //For name of the routine
 
  Full(int max, string m){
   maxElements = max; //put max in value in the object
   message = m; //put string in object
  }
};
There are public variables for a string object, which will hold the name of the member function being called, and a type int, for the MAX stack elements.

Initializing an Exception Object

How do we initialize the data when we throw an exception? In the two-argument constructor for the Stack class we say throw Full(MAX,"STACK PUSH --> Stack is FULL""); When the exception is thrown, the handler will display the string and MAX. The string will tell us which member function is throwing the exception, and the value of MAX. This additional data will make it easier for the programmer or user to figure out what caused the error.

Resources


PPT:
Video:
Web Resources:

Problem Set A:-

  1. Write an interactive program which divides two Integer Wrapper(Declaration is given) Class Objects. Overload divide(/) operator. Handle cases such as division-by-zero using exceptions. Write a test program to test the Wrapper Integer class for division.
The declaration of Integer class is
<source lang="cpp"> class Integer{ private: int value; public: Integer(int v){value=v;}; //Consturctor int getInt(); //returns the integer void setInt(int v); //set the int value to the object Integer operator/= (const Integer &); }; </source>

Problem Set B:-

  1. Add exceptions to the queue template you have written in Module 9. Throw two exceptions: one if the capacity of the queue is exceeded, the other if the program tries to remove an item from an empty queue. One way to handle this is to add a new data member to the queue: a count of the number of items currently in the queue. Increment the count when you insert an item, and decrement it when you remove an item. Throw an exception if this count exceeds the capacity of the queue, or if it becomes less than 0.
  2. Add Exceptions in the Dynamic Array if the Memory allocation failed.
  3. You might try making the main() part of this exercise interactive, so the user can put values on a queue and take them off. This makes it easier to exercise the queue. Following an exception, the program should allow the user to recover from a mistake without corrupting the contents of the queue.
____________________________________________________________________________





YOU ARE DONE WITH C++

It's time to work with real time 

world......




3 comments:

  1. where can i find the solutions to the programs??

    ReplyDelete
    Replies
    1. Specify your mail address. We will mail you the solutions.

      Delete
    2. Hi admin, can you mail me the solutions please.. my mail id : sr1kan7h@yahoo.in

      Delete