Cs6456 Notes
Cs6456 Notes
Cs6456 Notes
LECTURE NOTES
2014-2015(EVEN SEM)
Prepared by
Objects
Classes
Inheritance
Data Abstraction
Data Encapsulation
Polymorphism
Overloading
Reusability
Objects:
Object is the basic unit of object-oriented programming. Objects are identified
by its unique name. An object represents a particular instance of a class. There can be
more than one
instance of an object. Each instance of an object can hold its own relevant data.
An Object is a collection of data members and associated member functions also known
as methods.
Classes:
Classes are data types based on which objects are created. Objects with similar properties
and methods are grouped together to form a Class. Thus a Class represent a set of individual
objects. Characteristics of an object are represented in a class as Properties. The actions
that can be performed by objects becomes functions of the class and is referred to as Methods.
For example consider we have a Class of Cars under which Santro Xing, Alto and
WaganR
represents individual Objects. In this context each Car Object will have its own, Model,
Year of Manufacture, Colour, Top Speed, Engine Power etc., which form Properties of the Car
class and the associated actions i.e., object functions like Start, Move, Stop form the
Methods of Car Class.
No memory is allocated when a class is created. Memory is allocated only when an object
is created, i.e., when an instance of a class is created.
Inheritance:
Inheritance is the process of forming a new class from an existing class or base class. The
base class is also known as parent class or super class, The new class that is formed is called
derived class. Derived class is also known as a child class or sub class. Inheritance helps in
reducing the overall code size of the program, which is an important concept in object-oriented
programming.
Data Abstraction:
Data Abstraction increases the power of programming language by creating user defined
data types. Data Abstraction also represents the needed information in the program without
presenting the details.
Data Encapsulation:
Data Encapsulation combines data and functions into a single unit called Class. When using
Data Encapsulation, data is not accessed directly; it is only accessible through the functions present
inside the class. Data Encapsulation enables the important concept of data hiding possible.
Polymorphism:
Polymorphism allows routines to use variables of different types at different times. An
operator or function can be given different meanings or functions. Polymorphism refers to
a single function or multi-functioning operator performing in different ways.
Overloading:
Overloading is one type of Polymorphism. It allows an object to have different
meanings, depending on its context. When an exiting operator or function begins
to operate on new data type, or class, it is understood to be overloaded.
Reusability:
This term refers to the ability for multiple programmers to use the same written and
debugged existing class of data. This is a time saving device and adds code efficiency to
the language.
Additionally, the programmer can incorporate new features to the existing class, further
developing the application and allowing users to achieve increased performance. This time
saving feature optimizes code, helps in gaining secured applications and facilitates
easier maintenance on the application.
#include <iostream>
class employee // Class Declaration
{
private:
char empname[50];
int empno;
public:
void getvalue()
{
cout<<"INPUT Employee
Name:"; cin>>empname;
cout<<"INPUT Employee Number:";
cin>>empno;
void displayvalue()
{
cout<<"Employee Name:"<<empname<<endl;
cout<<"Employee Number:"<<empno<<endl;
}
};
main()
{
employee e1; // Creation of Object
e1.getvalue();
e1.displayvalue();
}
2.Programming Concepts:
Encapsulation
It is a mechanism that associates the code and the data it manipulates into a single unit to and
keeps them safe from external interference and misuse. In C++ this is supported by construct called
class. An instance of an object is known as object which represents a real world entity.
Data Abstraction
A data abstraction is a simplified view of an object that includes only features one is
interested in while hides away the unnecessary details. In programming languages, a data
abstraction becomes an abstract data type or a user-defined type. In OOP, it is implemented as
a class.
Inheritance:
Inheritance is a means of specifying hierarchical relationships between types C++
classes can inherit both data and function members from other (parent) classes. Terminology:
"the child (or derived) class inherits (or is derived from) the parent (or base) class".
Polymorphism:
Polymorphism is in short the ability to call different functions by just using one type of
function call. It is a lot useful since it can group classes and their functions together. Polymorphism
means that the same thing can exist in two forms. This is an important characteristic of true
object oriented design - which means that one could develop good OO design with data
abstraction and inheritance, but the real power of object oriented design
seems to surface when polymorphism is used.
Multiple Inheritance
The mechanism by which a class is derived from more than one base class is known as
multiple inheritance. Instances of classes with multiple inheritance have instance variables
for each of the inherited base classes.
Basic c++:
A class definition begins with the keyword class.
The body of the class is contained within a set of braces, { } ; (notice the semi-
colon). class class_name
{
….
….
….
};
Within the body, the keywords private: and public: specify the access level of the
members of the class.
–
the default is private.
Usually, the data members of a class are declared in the private: section of the class and
the member functions are in public: section.
class class_name
{
private:
…
…
…
public:
…
…
…
};
Example:
This class example shows how we can encapsulate (gather) a circle information into
one package (unit or class)
class Circle
{
private:
double radius;
public:
void setRadius(double r);
double getDiameter();
double getArea();
double getCircumference();
};
private
public
protected
A private member within a class denotes that only members of the same class have
accessibility. The private member is inaccessible from outside the class.
A protected access specifier is a stage between private and public access. If member
functions defined in a class are protected, they cannot be accessed from outside the class but can
be accessed from the derived class.
Data Members :
Data members include members that are declared with any of the fundamental types, as
well as other types, including pointer, reference, array types, bit fields, and user-defined types.
You can declare a data member the same way as a variable, except that explicit
initializers are not allowed inside the class definition. However, a const static data member of
integral or enumeration type may have an explicit initializer.
A class X cannot have a member that is of type X, but it can contain pointers to X,
references to X, and static objects of X. Member functions of X can take arguments of type X
and have a return type of X. For example:
class X
{
X();
X *xptr;
X &xref;
static X xcount;
X xfunc(X);
};
Static members:
Class members can be declared using the storage class specifier static in the class
member list. Only one copy of the static member is shared by all objects of a class in a program.
When you declare an object of a class having a static member, the static member is not
part of the class object.
You access a static member by qualifying the class name using the :: (scope resolution)
operator. In the following example, you can refer to the static member f() of class type X as
X::f() even if no object of type X is ever
declared: struct X {
static int
f(); };
int main()
{ X::f();
}
Function:
Functions are building blocks of the programs. They make the programs more modular
and easy to read and manage. All C++ programs must contain the function main( ). The
execution of the program starts from the function main( ). A C++ program can contain any
number of functions according to the needs. The general form of the function is: -
return_type function_name(parameter list)
{
body of the function
}
The function of consists of two parts function header and function body. The function
header is:-
return_type function_name(parameter list)
The return_type specifies the type of the data the function returns. The return_type can be
void which means function does not return any data type. The function_name is the name of the
function. The name of the function should begin with the alphabet or underscore.
The parameter list consists of variables separated with comma along with their data
types. The parameter list could be empty which means the function do not contain any
parameters. The parameter list should contain both data type and name of the variable. For
example,
int factorial(int n, float j)
is the function header of the function factorial. The return type is of integer which means
function should return data of type integer. The parameter list contains two variables n and j of type
integer and float respectively. The body of the function performs the computations.
Member functions are operators and functions that are declared as members of a class.
Member functions do not include operators and functions declared with the friend
specifier.
These are called friends of a class. You can declare a member function as static; this
is called a static member function. A member function that is not declared as static is called a
nonstatic member function.
The definition of a member function is within the scope of its enclosing class. The body
of a member function is analyzed after the class declaration so that members of that class can be
used in the member function body, even if the member function definition appears before the
declaration of that member in the class member list. When the function add() is called in the
following example, the data variables a, b, and c can be used in the body of add().
class x
{
public:
int add() // inline member function add
{return a+b+c;};
private: int
a,b,c; };
Special type of member function:
Constructor:
–
Public function member
–
called when a new object is created (instantiated).
–
Initialize data members.
–
Same name as class
–
No return type
–
Several constructors
Function overloading
class Circle
{
private: double
radius; public:
Circle(); Circle(int
r);
void setRadius(double r);
double getDiameter(); double
getArea();
double getCircumference(); };
Default arguments:
#include<iostream>
#include<iomanip> using
namespace std;
{
long sum=0;;
for(int i=0;i<n;i++)
{
cout<<setw(5)<<first_term+ diff*i;
sum+=first_term+diff*i;
}
return sum;
}
int main()
{
cout<<endl<<Sum=<<setw(7)< <sum(10)<<endl;
//first term=1; diff=1,n=10
//sums the series 1,2,3,4,5………10
cout<<endl<<Sum=<<setw(7)< <sum(6,3,2)<<endl;
//first term=1; diff=2,n=10
//sums the series 2,5,8,11,14,17
cout<<endl<<Sum=<<setw(7)< <sum(10,2)<<endl;
//first term=1; diff=2,n=10
//sums the series 1,3,5………..19
return 1;
}
all the parameters with default values should lie to the right in the signature list i.e.
the default arguments should be the trailing arguments—those at the end of the list.
when a function with default arguments is called, the first argument in the call statement
is assigned to the first argument in the definition, the 2nd to 2nd and so on.
This becomes more clear from the last call to sum() in the above example where value 10
is assigned to n and 2 is assigned to diff and not first_term.
Function Overloading:
*C++ supports writing more than one function with the same name but different
argument lists. This could include:
–
different data types
different number of arguments
*The advantage is that the same apparent function can be called to perform similar
but different tasks. The following will show an example of this .
void swap (int *a, int *b) ;
void swap (float *c, float *d) ;
void swap (char *p, char *q) ;
int main ( )
{
int a = 4, b = 6 ;
Friend Function:
*A friend function of a class is defined outside the class‘s scope (I.e. not
member functions), yet has the right to access the non-public members of the class.
*Single functions or entire classes may be declared as friends of a class.
*These are commonly used in operator overloading. Perhaps the most common use of
friend
functions is overloading << and >> for I/O.
*Basically, when you declare something as a friend, you give it access to your private
data members.
*This is useful for a lot of things – for very interrelated classes, it more efficient (faster)
than using tons of get/set member function calls, and they increase encapsulation by allowing
more freedom is design options.
*A class doesn't control the scope of friend functions so friend function declarations are
usually written at the beginning of a .h file. Public and private don't apply to them.
Example pgm//
class someClass
{
friend void setX( someClass&, int);
int someNumber;
… rest of class definition
}
c.someNumber = val; }
Const Functions :
If you declare a class method const, you are promising that the method won't change the
value of any of the members of the class. To declare a class method constant, put the
keyword const after the parentheses but before the semicolon. The declaration of the
constant member functionSomeFunction() takes no arguments and returns void. It looks like this:
void SomeFunction() const;
Access or functions are often declared as constant functions by using the const modifier
Declare member functions to be const whenever they should not change the object
Volatile Functions:
The volatile keyword is a type qualifier used to declare that an object can be modified
in the program by something such as the operating system, the hardware, or a concurrently
executing thread. If your objects are used in a multithreaded environment or they can be
accessed asynchronously (say by a signal handler), they should be declared volatile. A
volatile object can call only volatile member functions safely. If the program calls a
member function that isn't volatile, its behavior is undefined. Most compilers issue a warning if a
non-volatile member function is called by a volatile object:
struct S
{int f1();
int f2() volatile;
}
Static Members:
Object Oriented Programming in C++. A class member is either a property or a method.
A static member of a class is a member whose value is the same for every object instantiated.
This means that if one object changes the value of the static member, this change will be
reflected in another object instantiated from the class. The change (or the resulting value) will be
the same in all the instantiated objects. You can also access a static member using the class name
without instantiation. In this part of the series, we look at static members in C++
classes. You can have a static member along side other members in your class.
Static Property
A static property is also called a static data member.
Declaring a Static Property
You declare a static property just as you declare any other attribute, but you precede the
declaration expression with the keyword, static and a space. The syntax is:
static Type Ident;
Despite this simple feature, you have to learn how to use the static member. You do not
use it in the straightforward way.
Example
The following class illustrates the use of a static property member:
#include <iostream>
using namespace std;
class MyClass
{
public:
static int
sameAll; };
int MyClass::sameAll =
5; int main()
{
MyClass myObj;
myObj.sameAll = 6;
cout << MyClass::sameAll;
return 0;
}
In the code, you have a class called MyClass. This class has just one member, which is
the static data member. You initialize the static member outside the class description as shown
above. You begin with the return type of the static property. This is followed by a space and then
the name of the class. After that you have the scope operator, then the identifier of the static
property. Then you have the assignment operator and the value.
You instantiate an object form the class that has the static member in the normal way. Line
1
in the main function illustrates this. You access the static property of an instantiated object in
the normal way. The second line in the main function illustrates this. However, changing the value as
this line has done means changing the value for the class (description) and any
instantiated object and any object that is still to be instantiated.
The third line in the main function displays the static property value. It uses the class
name; it did not use the object name. To use the class name to access the static attribute, you
begin with the class name. This is followed by the scope operator and then the identifier of the
static property. This shows how you can access a static attribute with the class name directly and
without using an object; this is like accessing the property in the class description. The static
member is a kind of global object.
Objects:
In object-oriented programming language C++, the data and functions (procedures to
manipulate the data) are bundled together as a self-contained unit called an object. A class
is an extended concept similar to that of structure in C programming language, this class
describes the data properties alone. In C++ programming language, class describes both the
properties (data) and behaviors (functions) of objects. Classes are not objects, but they are used
to instantiate objects.
Creation of Objects:
Once the class is created, one or more objects can be created from the class as objects
are instance of the class.
int x;
exforsys e1;
class exforsys
{
private: int
x,y;
public:
void sum()
{
………
………
}
};
main()
{
exforsys e1;
……………
……………
}
The object can also be declared immediately after the class definition. In other words the
object name can also be placed immediately before the closing flower brace symbol } of the
class declaration.
Pointers and Objects:
#include <iostream>
using namespace
std; class myclass {
int i;
public:
myclass(int j) {
i = j;
}
int getInt() {
return i;
}
};
int main()
{
myclass ob(88), *objectPointer;
objectPointer = &ob; // get address of ob
cout << objectPointer->getInt(); // use -> to call
getInt() return 0;
}
Constant objects:
We've already seen const references demonstrated, and they're pretty natural: when you
declare a const reference, you're only making the data referred to const. References, by
their very nature, cannot change what they refer to. Pointers, on the other hand, have two ways
that you can use them: you can change the data pointed to, or change the pointer itself.
Consequently, there are two ways of declaring a const pointer: one that prevents you
from changing what is pointed to, and one that prevents you from changing the data pointed to.
On the other hand, if you just want the address stored in the pointer itself to be const, then
you have to put const after the *:
int x;
int * const p_int = &x;
Personally, I find this syntax kind of ugly; but there's not any other obviously better way
to do it. The way to think about it is that "* const p_int" is a regular integer, and that the value
stored in p_int itself cannot change--so you just can't change the address pointed to. Notice, by
the way, that this pointer had to be initialized when it was declared: since the pointer itself is
const, we can't change what it points to later on! Them's the rules.
Generally, the first type of pointer, where the data is immutable, is what I'll refer to as a
"const pointer" (in part because it's the kind that comes up more often, so we should have a
natural way of describing it).
Nested Classes:
§
A class can be declared within the scope of another class. Such a class is called a
"nested class." Nested classes are considered to be within the scope of the enclosing class
and are available for use within that scope. To refer to a nested class from a scope other than its
immediate enclosing scope, you must use a fully qualified name value class Outside { value
class Inside { }; }; In the same way, you can nest as many classes as you wish in another class
and you can nest as many classes inside of other nested classes if you judge it necessary.
Just as you would manage any other class so can you exercise control on a nested
class. For example, you can declare all necessary variables or methods in the nested class or in
the nesting class. When you create one class inside of another, there is no special programmatic
relationship between both classes: just because a class is nested doesn't mean that the nested
class has immediate access to the members of the nesting class. They are two different classes
and they can be used separately.
§
The name of a nested class is not "visible" outside of the nesting class. To access a
nested class outside of the nesting class, you must qualify the name of the nested class
anywhere you want to use it. This is done using the :: operator. For example, if you want
to declare an Inside variable somewhere in the program but outside of Outside, you must qualify
its name. Here is an example:
Local classes:
A local class is declared within a function definition. Declarations in a local class can
only use type names, enumerations, static variables from the enclosing scope, as well as external
variables and functions.
For example:
int x; // global variable
void f() // function definition
{
static int y; // static variable y can be used by
// local class
int x; // auto variable x cannot be used
by // local class
extern int g(); // extern function g can be used by
// local class
int main()
{
local* z; // error: the class local is not visible
// ...}
Member functions of a local class have to be defined within their class definition, if they
are defined at all. As a result, member functions of a local class are inline functions. Like all
member functions, those defined within the scope of a local class do not need the keyword inline.
A local class cannot have static data members. In the following example, an attempt to
define a static member of a local class causes an error:
void f()
{
class local
{
we want to program a card deck for a simple blackjack game we are programming.
Remember containership and inheritance? Let's think about the types of parts that make up
a deck -- and those are the cards. Since all of the cards are very similar in structure, we could use
a struct to represent a single card:
enum Suit = {Clubs, Spades, Diamonds,
Hearts}; struct Card {
Suit suit;
char digit;
};
A note on the digit. If digit <= 10, then it is a number, else it is the letter of the card (J, Q,
K, A). You could also use it as a number 1(ace) through 13(king) as well, perhaps if you were
using the card value in additions or such.
A simple object, the card deck only has one type of item. Now let's think about the types
of actions you can perform on the deck, and then make a class declaration out of this list, as well
as using the previously declared data.
class Deck
{ public:
void CreateDeck();//Fills array with legal cards
void Shuffle(); //Shuffles those cards
Card DrawCard(); //Gets a card from the deck
private:
Card cards[52];
};
Now we have considered all of the things we may need to use a card deck. The programmer first
sets up the deck with CreateDeck(), then whenever needed can Shuffle() the deck, and when the
dealer deals a card, it can be picked up using DrawCard(), and then perhaps placed in the
players hand (which could also could be a class too) or whatever the programmer needs to do
with it.
Deck::Deck() {
cards = new Card[52];//Allocate
memory CreateDeck(); //Set up the deck
}
Deck::~Deck() {
delete[] cards; //Deallocate memory
The programmer cannot declare a constructor as virtual or static, nor can the
programmer declare a constructor as const, volatile, or const volatile.
The constructor must be defined in the public. The constructor must be a public
member.
Example
class A
{
public:
A(){/*body*/} //Deafult constructor without arquemnet
or
if you did not write any constructor within class A. The implicit constructor or inline
constructor A::A() /*[without no body] */ will be called when you create object for
class A
Note: you can't use both constructor in same class. Confilict occur when you create
object of class A that whether to call first one or second one (ambiguity)
This constructor has no arguments in it. Default Constructor is also called as no argument
constructor.
For
class Exforsys
example:
{
private:
int a,b;
public:
Exforsys();
...
};
Exforsys :: Exforsys()
{
a=0;
b=0;
In C++, default constructors are significant because they are automatically invoked
in certain circumstances:
When an object value is declared with no argument list, e.g. MyClass x;; or allocated
dynamically with no argument list, e.g. new MyClass; the default constructor is used
to initialize the object
When an array of objects is declared, e.g. MyClass x[10];; or allocated dynamically, e.g.
new MyClass [10]; the default constructor is used to initialize all the elements
When a derived class constructor does not explicitly call the base class constructor in
its initializer list, the default constructor for the base class is called
When a class constructor does not explicitly call the constructor of one of its object-valued
fields in its initializer list, the default constructor for the field's class is called In the
standard library, certain containers "fill in" values using the default constructor when the value is
not given explicitly, e.g. vector<MyClass>(10); initializes the vector with 10
elements, which are filled with the default-constructed value of our type.
In the above circumstances, it is an error if the class does not have a default constructor.
The compiler will implicitly define a default constructor if no constructors are explicitly
defined for a class. This implicitly-declared default constructor is equivalent to a
default constructor defined with a blank body.
(Note: if some constructors are defined, but they are all non-default, the compiler will not
implicitly define a default constructor. This means that a default constructor may not exist for a
class.).
These are access specifiers for class data members and member
methods. 1.
Public: The data members and methods having public as access specifier can be
accessed by the class objects created outside the class.
2.
Protected: The data members and methods declared as protected will be accessible to the
class methods and the derived class methods only.
3.
Private: These data members and methods will be accessible from the class methods
only not from derived classes and not from objects created outside the class.
4.
Internal: Some languages define internal as an access specifier which means the data
member or method is available to all the classes inside that particular assembly.
5.
Friend: A friend class or method can access all data of a class including private
and protected data.
// A parameterized constructor.
using System;
class MyClass {
public int x;
public MyClass(int i)
{ x = i;
}
}
void YourClass::deleteAll()
{
delete ptr1; ptr1 = 0;
delete ptr2; ptr2 = 0;
delete ptr3; ptr3 = 0;
}
YourClass::YourClass():
ptr1(0), ptr2(0), ptr3(0)
{
try
{
ptr1 = new whatever; ptr2
= new whatever; ptr3 =
new whatever;
}
catch(...)
{
deleteAll();
}
}
YourClass::~YourClass()
{
deleteAll();
}
This constructor takes one argument. Also called one argument constructor. The main use
of copy constructor is to initialize the objects while in creation, also used to copy an
object. The copy constructor allows the programmer to create a new object from an existing one
by initialization.
Exforsys e3(e2);
or
Exforsys e3=e2;
Copy constructor is
1. a constructor function with the same name as the class
2. used to make deep copy of objects.
There are 3 important places where a copy constructor is called.
1. When an object is created from another object of the same type
2. When an object is passed by value as a parameter to a function
3. When an object is returned from a function.
If a copy constructor is not defined in a class the compiler itself defines one. This
will ensure a shallow copy. If the class does not have pointer variables with dynamically
allocated memory then one need not worry about defining a copy constructor. It
can be left to the compiler's discretion.
For Example:
#include <iostream.h>
class Exforsys()
{
private: int a;
public: Exforsys()
{}
Exforsys(int w)
{
a=w;
}
Exforsys(Exforsys& e)
{
a=e.a;
cout<<‖ Example of Copy Constructor‖;
}
void result()
{
cout<< a;
}
};
void main()
{
Exforsys e1(50); Exforsys
e3(e1); cout<< ―=‖;e3.result();
}
In the above the copy constructor takes one argument an object of type Exforsys which is passed
by reference. The output of the above program is
Constructor is called when an object is created.Copy constructor is called when the copy
of an object is made. For e.g. passing parameter to function by value function returning by
value. Copy constructor takes the parameter as const reference to the object.
Destructors
The destructor of an automatic object is called when the object goes out of scope.
The destructor itself does not actually destroy the object, but it does perform
termination housekeeping before the system reclaims the object‘s.
The above is the general syntax of a destructor. In the above, the symbol tilda ~
represents a destructor which precedes the name of the class.
Some important points about destructors:
Like the constructor, the destructor must also be defined in the public. The destructor
must be a public member.
The Destructor does not take any argument which means that destructors cannot
be overloaded.
class Exforsys
{
private:
……………
public:
Exforsys()
{}
~ Exforsys()
{}
}
Like constructor the destructor is a member function whose name is the same as the
class name but is preceded by a tilde. For example the destructor of a class integer
can be define as :-
~integer(){}
A destructor never takes any argument nor does it return any value. It will invoked
implicitly by the compiler upon exit from the program to clean up storage that is no
longer accessible.
Re: What is role of constructor and destructor in C++?
The constructor's job is to set up the object so that it can be used.Destructors are less
complicated than constructors. You don't call them explicitly (they are called automatically for
you), and there's only one destructor for each object. The name of the destructor is the name of
the class, preceeded by a tilde.
Operator Overloading
Operator Overloading in two Parts, In Part I of Operator Overloading you will learn about
Unary Operators, Binary Operators and Operator Overloading – Unary operators.
After knowing about the feature of operator overloading now let us see how to define
and use this concept of operator overloading in C++ programming language.
Unary Operators
Binary Operators
Unary Operators:
As the name implies takes operate on only one operand. Some unary operators are namely
++
called as Increment operator, -- called as Decrement Operator, ! , ~, unary minus.
Binary Operators:
The arithmetic operators, comparison operators, and arithmetic assignment operators
all this which we have seen in previous section of operators come under this category.
Both the above classification of operators can be overloaded. So let us see in detail each of
this.
Thus the above clearly specifies that operator overloading is defined as a member
function by making use of the keyword operator.
In the above:
:: - is the scope resolution operator which is used to use the function definition outside the
class. The usage of this is clearly defined in our earlier section of How to define class members.
For example
Suppose we have a class say Exforsys and if the programmer wants to define a operator
overloading for unary operator say ++, the function is defined as
Inside the class Exforsys the data type that is returned by the overloaded operator is defined
as
Class Exforsys
{
Private :
……….
Public :
void operator++();
……….
};
Inside the class the operator overloaded member function is defined with the return data
type as member function or a friend function. The concept of friend function we will define in
later sections. If in this case of unary operator overloading if the function is a member function
then the number of arguments taken by the operator member function is none as
seen in the below example. In case if the function defined for the operator overloading is
a friend function which we will discuss in later section then it takes one argument.
The operator overloading is defined as member function outside the class using the scope
resolution operator with the keyword operator as explained above
Now let us see how to use this overloaded operator member function in the program
#include<iostream.h>
classExforsys
{
private:
int
x;
public:
Exforsys( )
{x=0;
} //Constructor
void
display();
void
Exforsys++();
};
Void Exforsys::display()
{
cout<<‖ of
x is:―<<x;
}
void Exforsys::operator ++( )//Operator Overloading for operator ++ defined
{
++x;
}
Void main()
{
Exforsys e1,e2; //Object e1 and e2 created cout<<‖Before
Increment‖
cout<<‖:‖<<e1.display();
cout<<‖
e2:‖<<e2.display();
++e1; //Operator overloading
applied
++e2;
cout<<‖
After Increment‖ cout<<‖
e1:‖<<e1.display(); cout
<<‖e2:
‖<<e2.display();
}
The output of the above program is:
Object e1:
Value of x is: 1
In the above example we have created 2 objects e1 and e2 f class Exforsys. The
operator ++ is overloaded and the function is defined outside the class Exforsys.
When the program starts the constructor Exforsys of the class Exforsys initialize
the values as zero and so when the values are displayed for the objects e1 and e2 it is
displayed as zero.
When the object ++e1 and ++e2 is called the operator overloading function
gets applied and thus value of x gets incremented for each object separately. So now
when the values are
displayed for objects e1 and e2 it is incremented once each and gets printed as
one for each object e1 and e2.
This is how unary operators get overloaded. We will see in detail how to
overload binary operators in next section.
when a data is declared as private inside a class, then it is not accessible from
outside the class. A function that is not a member or an external class will not be able
to access the private data. A programmer may have a situation where he or she would
need to access
private data from non-member functions and external classes. For handling such
cases, the concept of Friend functions is a useful tool.
What is a Friend Function?
A friend function is used for accessing the non-public members of a class. A
class can allow non-member functions and other classes to access its own private data,
by making them
friends. Thus, a friend function is an ordinary function or a member of another
class.
How to define and use Friend Function in C++:
The friend function is written as any other normal function, except the function
declaration of these functions is preceded with the keyword friend. The friend function
must have the class to which it is declared as friend passed to it in argument.
#inc
lude
clas
s
exfo
rsys
{
p
r
i
v
a
t
e
:
i
n
t
a
,
b
;
p
u
b
l
i
c
:
v
o
i
d
t
e
s
t
(
)
{
a=100;
b=200;
}
friend int compute(exforsys e1)
main()
{
e
x
f
o
r
s
y
s
e
;
e
.t
e
s
t
(
)
;
cout<<"The result is:"<<COMPUTE(E);
//Calling of Friend Function with object as argument.
}
String
abc ;
String
s1
Hello ;
String s2 Geek
Interview ; abc
s1+s2;
Sop(abc);
would print Hello Geek Interview
Compound assignment Operators denoted by +=, -=, *=, /=, %=, >>=,
<<=, &=, ^=, |=
Relational and equality operators denoted by ==, !=, >, <, >=, <=
sizeof()
Assignment Operator
This is denoted by symbol =. This operator is used for assigning a value to a
variable. The left of the assignation operator is known as the lvalue (left value), which
must be a variable. The right of the assignation operator is known as the rvalue (right
value). The rvalue can be a constant, a variable, the result of an operation or any
combination of these.
For
exa
mpl
e: x
= 5;
By following the right to left rule the value 5 is assigned to the variable x in
the above assignment statement.
Arithmetic operators
The operators used for arithmetic operation sin C++ are:
+ For addition
- For subtraction
* For multiplication
/ For division
% For modulo
Compound assignment Operators
This operator is used when a programmer wants to update a current value by
performing operation on the current value of the variable.
For example:
O
l
d
+
=
n
e
w
i
s
equal to
Old = old + new
Compound assignment operators function in a similar way the other operators
+=, -=, *=,
/=,
%=, >>=, <<=, &=, ^=, |= function.
Increment and Decrement Operator
The increment operator is denoted by ++ and the decrement operator by --. The
function of the increment operator is to increase the value and the decrement operator is
to decrease the value. These operators may be used as either prefix or postfix. A Prefix
operator is written before the variable as ++a or –a. A Postfix operator is written after
the variable as a++ or a--.
The Functionality of Prefix and Postfix Operators
In the case that the increment or decrement operator is used as a prefix ( ++a or
–a), then the value is respectively increased or decreased before the result of the
expression is evaluated.
Therefore, the increased or decreased value, respectively, is considered in the outer
expression. In the case that the increment or decrement operator is used as a postfix
(a++ or
a--), then the value stored in a is respectively increased or decreased after being
evaluated.
For Example:
y=3;
== Equal to
!= Not equal to
If the operation modifies the state of the class object it operates on it must
be a member function not a friend function Thus all operator such as * + etc
are naturally defined as member functions not friend functions Conversely
if the operator does not modify any of its operands but needs only a
representation of the object it does not have to be a member function and
often less confusing. This is the reason why binary operators are often
implemented as friend functions such as + * - etc..
Because assignment operator is one of the default method provided by the class.
Type Conversion
In C++ the type casting can be done in either of the two ways mentioned
below namely: C-style casting
C++-style casting
This approach was adopted since it provided more clarity to the C++
programmers rather
t
h
a
n
t
h
e
C-style casting.
Say for instance the as per C-
style casting (type) firstVariable
* secondVariable
is not clear but when a programmer uses the C++ style casting it is much more
clearer as below
type (firstVariable) * secondVariable
Let us see the concept of type casting in C++ with a small
example: #include
<io
stre
am.
h>
voi
d
main()
{
i
n
t
a
;
f
l
o
a
t
b
,
c
;
cout<< ―Enter the
value of a:‖; cin>>a;
cout<< ―n Enter the
value of b:‖; cin>>b;
c=float(a)+b;
cout<<‖n
T
h
e
v
a
l
u
e
o
f
i
s
:
‖
<
<
c
;
}
E
n
t
e
r
t
h
e
v
a
l
u
e
o
f
a
:
10
E
n
t
e
r
t
h
e
v
a
l
u
e
o
f
b
:
12.5
The value of c is: 22.5
In the above program a is declared as integer and b and c are declared as float.
In the type conversion statement namely
c = float(a)+b;
The variable a of type integer is converted into float type and so the value 10 is
converted as 10.0 and then is added with the float variable b with value 12.5 giving a
resultant float variable
Explicit Constructor
Explicit Constructor
class Array
{
public:
Array(size
_t count);
// etc.
};
explicit B (const A& aObj)
But explicit on a constructor with multiple arguments has no effect, since such
constructors cannot take part in implicit conversions. However, explicit will have an
effect if a constructor has multiple arguments and all but one of the arguments has a
default value.
For Example:
The code
Code: Cpp
#include<ios
tream.h>
class A
{
int
da
ta
1;
int
da
ta
2;
ch
ar
*
na
m
e;
public:
A(int a, int b=10, char* c = "mridula"):data1(a), data2(b), name(c)
{
cout<<"A::Const
rucor... "; };
friend void
display(A obj);
};
int main()
{
//Call display with A
object i.e. a1
display(100);
return (0);
}
Output:
----------
./a.out
A::Con
strucor
...
Valud of data1 in obj :=
100 Valud of data2 in
obj := 10 Valud of name
in obj := mridula
As said above, it is better to use explicit for such constructor declaration too to
avoid any such implicit conversions.
INHERITANCE:
Let us start by defining inheritnace. A very good website for finding computer science
definitions is http://www.whatis.com. The definitions in this article are stolen from
that website.
Definition:
Inheritance
Inheritance is the concept that when a class of object is defined, any subclass that is
defined can inherit the definitions of one or more general classes. This means for the
programmer that an object in a subclass need not carry its own definition of data and
methods that are generic to the class (or classes) of which it is a part. This not only
speeds up program development; it also ensures an inherent validity to the defined
subclass object (what works and is consistent about the class will also work for
the subclass).
The simple example in C++ is having a class that inherits a data member from its parent
class.
class A
{
public:
integer d;
};
class B : public A
{
public:
};
The class B in the example does not have any direct data member does it? Yes, it
does. It
inherits the data member d from class A. When one class inherits from another, it
acquires all of its methods and data. We can then instantiate an object of class B and
call
TYPES OF INHERITANCE:
1. Single Inheritance
2. Multiple Inheritance
3. Multilevel Inheritance
4. Hierarchial Inheritance
You can derive a class from any number of base classes. Deriving a class
from more than one direct base class is called multiple inheritance.
In the following example, classes A, B, and C are direct base classes for the
derived class X:
class A { /*
... */ }; class
B { /* ... */
}; class C {
/* ... */ };
class X : public A, private B, public C { /* ... */ };
A direct base class cannot appear in the base list of a derived class more than
once:
However, a derived class can inherit an indirect base class more than once, as
shown
in the following example:
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 subobjects
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:
You can also avoid this ambiguity by using the base specifier virtual to
declare a base class, as described in Derivation (C++ only).
VIRTUAL BASE CLASSES (C++ ONLY)
Suppose you have two derived classes B and C that have a common base class A,
and you also have another class D that inherits from B and C. You can declare the
base class A
as virtual to ensure that B and C share the same subobject of A.
In the following example, an object of class D has two distinct subobjects of class
L,
one through class B1 and another through class B2. You can use the keyword
virtual in front of the base class specifiers in the base lists of classes B1 and B2 to
indicate that only one subobject of type L, shared by class B1 and class B2, exists.
For example:
class V { /* ... */ };
class B1 : virtual public V { /*
... */ }; class B2 : virtual
public V { /* ... */ }; class B3
: public V { /* ... */ };
class X : public B1, public B2, public B3 {
/* ... */ };
In the above example, class X has two subobjects of class V, one that is shared by
classes
B1
and B2 and one through class B3.
VIRTUAL FUNCTIONS:
C++ matches a function call with the correct function definition at
compile time known as static binding
the compiler can match a function call with the correct function
definition at run time known as dynamic binding.
declare a function with the keyword virtual if you want the compiler to use
dynamic binding for that specific function.
Example:
class A {
public:
virtual void f() { cout << "Class A"
<< endl; } };
class B:
public A {
public:
void f(int) { cout << "Class B"
<< endl; } };
class C:
public B {
public:
void f() { cout << "Class C"
<< endl; } };
Example:
class A {
public:
virtual void f() = 0; // pure
virtual };
class B: public A
{ public:
void f() { cout << "Class B" << endl;
} };
class C: public B
{ public:
void f() { cout << "Class C" << endl;
} };
Run Time Type Information (RTTI)
Always exists in OOP: a prerequisite for dynamic binding
Accessible to programmer?
Not necessarily in statically typed languages
Many things can be done without it!
Almost always in dynamically typed languages
Without it, it is impossible to be sure that an object will recognize a
message! In LST, RTTI is the information accessible from the instance_of
pointer Dynamic binding and casting:
Dynamic Typing: no constraints on the values stored in a variable.
– Usually implies reference semantics
•
Run‐time type information: dynamic type is
•
associated with the value.
–
–
};
Dynamic casting:
•
Casting operator is for polymorphic object casting ,so that it can cast from one object
to another object.
•
Dynamic cast is also called as safe cast.it succeeds only when the pointer or
reference being cast is an object of the target type or derived type from it.
•
The syntax is written as dynamic cast<ToobjectptrOr ref>(FromobjectPtrOrRef)
•
If we have a base class and a derived class,casting from derived pointer to base
pointer always succeeds.The casting from base pointer to derived can be succeed only
if base is actually pointing to an object of derived one.
Rtti and templates:
•
If we want to test the type of the actual variable and try to provide validations
according to the type we can use RTTI for that.
Cross casting:
It refers to casting from derived to proper base class when there are multiple
base classes in case of multiple inheritance.
The dynamic_cast feature of C++ affords another kind of solution -- cross
casting. Consider the following code.
class A {public: virtual ~A();};
class C : public A, public B
{}; A* ap = new C;
B* bp = dynamic_cast<B*>(ap);
Notice that classes A and are completely unrelated. Now when we create an
instance of C we can safely upcast it to an . However, we can now take that pointer to
A and it to a pointer to a B. This works because the A pointer ‗ ap ‘ really points at
a C object; and C derives from B Thus, we have cast accross the inheritance
hierarchy between completely unrelated classes. It should be noted that this will
not work with regular casts since they will not be able to do the address arithmetic
to get the pointer to B correct.
For example: B*
bp = (B*)ap;
While this will compile without errors , it will not generate working code. The value
of ‗ bp ‘ will not actually point to the B part of C. Rather it will still point at the A
part of C.
IOSTREAM LIBRARY
-
In Module 5 you have learned the formatted I/O in C by calling various
standard functions. In this Module we will discuss how this formatted I/O implemented in
C++ by using member functions and stream manipulators.
-
The header files used for formatted I/O in C++ are:
Header file
iostream.h
• Provide basic information required for all stream I/O operation such as cin, cout,
cerr and clog correspond to standard input stream, standard output stream, and
standard unbuffered and buffered error streams respectively.
iomanip.h
• Contains information useful for performing formatted I/O with parameterized stream
manipulation.
fstream.h
• Contains information for user controlled file processing
operations. strstream.h
• Contains information for performing in-memory formatting or in-core formatting.
This resembles file processing, but the I/O operation is performed to and from character
arrays rather than files.
stdiostrem.h
• Contains information for program that mixes the C and C++ styles of I/O.
iostream library
- The compilers that fully comply with the C++ standard that use the template
based header files won‘t need the .h extension. Please refer to Module 23 for more
information.
- The iostream class hierarchy is shown below. From the base class ios, we have
a derived class:
Class
istream
•
Class for stream input operation.
ostream
•
Class for stream output operation.
ios derived classes
-
So, iostream support both stream input and output. The class hierarchy
is shown below.
Left and Right Shift Operators
- We have used these operators in most of the Modules in this Tutorial for C++ codes.
- The left shift operator (<<) is overloaded to designate stream output and is called
stream insertion operator.
- The right shift operator (>>) is overloaded to designate stream input and is
called stream extraction operator.
-
These operators used with the standard stream object (and with other
user defined stream objects) is listed below:
Operators
cin
•
Object of istream class, connected to the standard input device, normally the
keyboard.
cout
•
Object of ostream class, connected to standard output device, normally the display
screen.
- For file processing C++ uses (will be discussed in another Module) the following classes:
Class
•
ifstream
To perform file input operations.
•
ofstream
For file output operation.
•
fstream
For file input/output operations.
Stream output program example:
//string output using <<
#include <stdlib.h>
#include <iostream.h>
void main(void)
{
cout<<"Welcome to C++ I/O module!!!"<<endl;
cout<<"Welcome to ";
cout<<"C++ module 18"<<endl;
//endl is end line stream manipulator
//issue a new line character and flushes the output buffer
//output buffer may be flushed by cout<<flush; command
system("pause");
}
get() and getline() Member Functions of Stream Input
- For the get() function, we have three versions.
1. get() without any arguments, input one character from the designated streams including
whitespace and returns this character as the value of the function call. It will
return EOF when end of file on the stream is encountered. For example:
2. cin.get();
3. get() with a character argument, inputs the next character from the input stream
including whitespace. It return false when end of file is encountered while returns a
reference to the istream object for which the get member function is being invoked. For example:
4. char ch;
5. cin.get(ch);
7. get() with three arguments, a character array, a size limit and a delimiter (default
value ‗‘). It reads characters from the input stream, up to one less than the specified
Program example:
//Using read(), write() and gcount() member functions
#include <stdlib.h>
#include <iostream.h>
const int SIZE = 100;
void main(void)
{
char buffer[SIZE];
cout<<"Enter a line of
text:"<<endl; cin.read(buffer,45);
cout<<"The line of text entered was:
"<<endl; cout.write(buffer, cin.gcount());
//The gcount() member function returns www.tenouk.com
//the number of unformatted characters last extracted
cout<<endl;
system("pause");
}
Stream Manipulators
-
Used to perform formatting, such as:
▪ Setting field width.
▪ Precision.
▪ Unsetting format flags.
▪ Flushing stream.
▪ Inserting newline in the output stream and flushing the stream.
▪ Inserting the null character in the output stream.
▪ Skipping whitespace.
▪ Setting the fill character in field.
Stream Base
-
For stream base we have:
Operator/function
•
hex
To set the base to hexadecimal, base 16.
•
oct
To set the base to octal, base 8.
•
dec
To reset the stream to decimal.
•
setbase()
Changing the base of the stream, taking one integer argument of 10, 8 or 16 for decimal,
base 8 or base 16 respectively. setbase() is parameterized stream manipulator by taking
argument, we have to include iomanip.h header file.
Table 18.5: Stream base operator and function.
Program example:
//using hex, oct, dec and setbase stream
manipulator #include <stdlib.h>
#include <iostream.h>
#include <iomanip.h>
void main(void)
{
int p;
cout<<"Enter a decimal number:"<<endl;
cin>>p;
cout<<p<< " in hexadecimal is: "
<<hex<<p<<''
<<dec<<p<<" in octal is:
" <<oct<<p<<''
<<setbase(10) <<p<<" in decimal is: "
<<p<<endl;
cout<<endl;
system("pause"); www.tenouk.com
}
Floating-point Precision
- Used to control the number of digits to the right of the decimal point.
- Use setprecision() or precision().
- precision 0 restores to the default precision of 6 decimal points.
//using precision and setprecision
#include <stdlib.h>
#include <iostream.h>
#include <iomanip.h> #include
<math.h> void main(void)
{
double theroot = sqrt(11.55);
cout<<"Square root of 11.55 with various"<<endl;
cout<<" precisions"<<endl; cout<<"---------------------------
------"<<endl; cout<<"Using 'precision':"<<endl;
for(int poinplace=0; poinplace<=8; poinplace++)
{
cout.precision(poinplace);
cout<<theroot<<endl;
}
cout<<"'setprecision':"<<endl;
for(int poinplace=0; poinplace<=8; poinplace++)
cout<<setprecision(poinplace)<<theroot<<endl;
system("pause");
}
Field Width
- Sets the field width and returns the previous width. If values processed are smaller than the
field width, fill characters are inserted as padding. Wider values will not be truncated.
- Use width() or setw(). For example:
cout.width(6); //field is 6 position wide
Program example:
//using width member function #include
<iostream.h> #include <stdlib.h>
void main(void)
{
int p = 6;
char string[20];
cout<<"Using field width with setw() or width()"<<endl;
cout<<"----------------------------------------"<<endl; cout<<"Enter
a line of text:"<<endl;
cin.width(7); while
(cin>>string)
{
cout.width(p++);
cout<<string<<endl;
cin.width(7);
//use ctrl-z followed by return key or ctrl-d to exit
}
system("pause");
}
Stream Format States
- Format state flag specify the kinds of formatting needed during the stream operations.
- Available member functions used to control the flag setting are: setf(), unsetf() and
flags().
- flags() function must specify a value representing the settings of all the flags.
- The one argument, setf() function specifies one or more ORed flags and ORs them with
the existing flag setting to form a new format state.
- The setiosflags() parameterized stream manipulator performs the same functions as the
setf.
- The resetiosflags() stream manipulator performs the same functions as the unsetf()
member function. For parameterized stream manipulators you need iomanip.h header file.
- Format state flags are defined as an enumeration in class ios.
ios::skipws
Use to skip whitespace on input.
ios::adjustfield
Controlling the padding, left, right or internal.
ios::left
Use left justification.
ios::right
Use right justification.
ios::internal
Left justify the sign, right justify the magnitude.
ios::basefield
Setting the base of the numbers.
ios::dec
Use base 10, decimal.
ios::oct
Use base 8, octal.
ios::hex
Use base 16, hexadecimal.
ios::showbase
Show base indicator on output.
ios::showpoint
Shows trailing decimal point and zeroes.
ios::uppercase
Use uppercase for hexadecimal and scientific notation values.
ios::showpos
Shows the + sign before positive numbers.
ios::floatfield
To set the floating point to scientific notation or fixed format.
ios::scientific
Use scientific notation.
ios::fixed
Use fixed decimal point for floating-point numbers.
ios::unitbuf
Flush all streams after insertion.
ios::stdio
Flush stdout, stderr after insertion.
- skipws flags indicates that >> should skip whitespace on an input stream. The
default behavior of >> is to skip whitespace. To change this, use the unsetf(ios::skipws). ws
stream manipulator also can be used for this purpose.
- ios::showpoint – this flag is set to force a floating point number to be output with its
decimal point and trailing zeroes. For example, floating point 88.0 will print 88 without
showpoint set and 88.000000 (or many more 0s specified by current precision) with
showpoint set.
///Using showpoint
//controlling the trailing zeroes and floating
points #include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
void main(void)
{
cout<<"Before using the ios::showpoint flag"
<<"------------------------------------"<<endl;
cout<<"cout prints 88.88000 as: "<<88.88000
<<"prints 88.80000 as: "<<88.80000
<<"prints 88.00000 as: "<<88.00000
<<"using the ios::showpoint flag" <<"---------
--------------------------"<<endl;
cout.setf(ios::showpoint);
cout<<"cout prints 88.88000 as: "<<88.88000
<<"prints 88.80000 as: "<<88.80000
<<"prints 88.00000 as: "<<88.00000<<endl;
system("pause");
}
Justification
- Use for left, right or internal justification.
- ios::left – enables fields to be left-justified with padding characters to the right.
- ios::right – enables fields to be right-justified with padding characters to the left.
- The character to be used for padding is specified by the fill or setfill.
- internal – this flag indicates that a number‘s sign (or base if ios::showbase flag is set)
should be left-justified within a field, the number‘s magnitude should be right-justified and the
intervening spaces should be padded with the fill character.
- The left, right and internal flags are contained in static data member ios::adjustfield, so
ios::adjustfield argument must be provided as the second argument to setf when setting the
right, left or internal justification flags because left, right and internal are mutually exclusive.
//using setw(), setiosflags(), resetiosflags() manipulators //and setf and unsetf member functions
#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h> void
main(void)
{
long p = 123456789L;
//L - literal data type qualifier for long...
//F - float, UL unsigned integer...
cout<<"The default for 10 fields is right justified:"
<<setw(10)<<p
<<"member function" <<"-----
----------------"
<<"setf() to set ios::left:"<<setw(10);
cout.setf(ios::left,ios::adjustfield);
cout<<p<<"unsetf() to restore the default:";
cout.unsetf(ios::left);
cout<<setw(10)<<p
<<"parameterized stream manipulators" <<"-------
--------------------------------" <<"setiosflags() to set
the ios::left:"
<<setw(10)<<setiosflags(ios::left)<<p
<<"resetiosflags() to restore the default:"
<<setw(10)<<resetiosflags(ios::left) <<p<<endl;
system("pause");
}
Padding
- fill() – this member function specify the fill character to be used with adjusted field. If no value
is specified, spaces are used for padding. This function returns the prior padding
character.
- setfill() – this manipulator also sets the padding character.
File Handling
•Examples
$handle = fopen("/home/wrfile.txt","w");
# the file will be created if it doesn't exist,
if it does exist you will overwrite whatever is currently in the
file File Open Examples
•open a file for binary writing
•In Windows you should be careful to escape any backslashes used in the path to the file
$handle = fopen("c:\data\file.txt", "r");
$handle = fopen("http://www.superduper.
com/file.txt", "r");
Pass this function the file handle to an open file, and an optional length. Reading ends
when length - 1 bytes have been read, on a newline (which is included in the return value), or on
encountering the end of file, whichever comes first. If no length is specified, the default length is
1024 bytes. (file.txt below)
Here
is
the
file.
$handle = fopen("file.txt","r");
while (!feof($handle))
{
$text = fgets ($handle);
}
fclose($handle);
Reading Characters: fgetc
•The fgetc function let's you read a single character from an open file.
Here's
the file
contents.
{
if ($char == "")
{
$char = "<br />";
}
echo "$char";
}
fclose($fhandle);
•Binary Reading: fread
•Files don't have to be read line by line, you can read a specified number of bytes (or until
the end-of-file is reached). The file is treated as a simple binary file of bytes.
$handle = fopen("file.txt","rb");
$text = fread($handle, filesize("file.txt");
$text = file_get_contents("file.txt");
$br_text = str_replace("","<br />",$text);
echo $br_text;
Careful with this function, for very large files, it can be a problem since the entire file
must be memory resident at one time.
Parsing a File
To make it easier to extract data from a file, you can format that file (using, for example,
tabs) and use fscanf to read your data from the file.
In general -----
fscanf ( resource handle, string format);
•Parsing a file: fscanf (cont.)
•This function takes a file handle, handle, and format, which describes the format of the
file you're working with. You set up the format in the same way as with sprintf, which was
discussed in Chapter 3. For example, say the following data was contained in a file names
tabs.txt, where the first and last names are separated by a tab.
George Washington
Benjamin Franklin
Thomas Jefferson
$fh = fopen("tabs.txt", "rb");
while ($names = fscanf($fh, "%s%s"))
{
list($firstname,$lastname) = $names; echo
$firstname, " ", $lastname, "<br />";
}
fclose ($fh);
Writing to a File: fwrite
•Write to a file with fwrite.
fwrite (resource fh, string str [, int length]);
The fwrite function writes the contents of str to the file stream represented by fh.
The writing will stop after length bytes have been written or the end of the string is reached.
fwrite returns the number of bytes written or FALSE if there was an error. If
you're working on a Windows system the file must be opened with 'b' included in the
fopen mode parameter.
$fh = fopen("text.txt","wb");
$text = "Here.";
if (fwrite($fh, $text) == FALSE)
{
echo "Cannot write to text.txt.";
}
else {
echo "Created the file text.txt.";
}
fclose($fh);
Appending to a File: fwrite
•In this case open the file for appending, using the file mode 'a':
$fh = fopen("text.txt","ab");
Append this to text.txt:
And here is
more text.
$text = "Here.";
if (file_put_contents("text.txt",$text) ==
FALSE)
{
echo "Cannot write to text.txt.";
}
else {
echo "Wrote to the file text.txt";
}
Random Access
This lesson is about using random access files in C and the following lesson will look at
working with text files. Apart from the simplest of applications, most programs have to read or
write files. Maybe it's just for reading a config file, or a text parser or something more
sophisticated. The basic file operations are
fopen - open a file- specify how its opened (read/write) and type (binary/text)
Object serialization consists of saving the values that are part of an object, mostly the
value gotten from declaring a variable of a class. AT the current standard, C++ doesn't inherently
support object serialization. To perform this type of operation, you can use a technique
known as binary serialization.
When you decide to save a value to a medium, the fstream class provides the option to
save the value in binary format. This consists of saving each byte to the medium by aligning
bytes in a contiguous manner, the same way the variables are stored in binary numbers.
To indicate that you want to save a value as binary, when declaring the ofstream
variable, specify the ios option as binary. Here is an example:
#include <fstream>
#include <iostream>
using namespace std;
class Student
{
public:
char FullName[40];
char CompleteAddress[120];
char Gender;
double Age;
bool LivesInASingleParentHome;
};
int main()
{
Student one;
strcpy(one.FullName, "Ernestine Waller");
strcpy(one.CompleteAddress, "824 Larson Drv, Silver Spring, MD
20910"); one.Gender = 'F';
one.Age = 16.50;
one.LivesInASingleParentHome
= true; ofstream
ofs("fifthgrade.ros", ios::binary);
return 0;
}
Writing to the Stream
The ios::binary option lets the compiler know how the value will be stored.
This declaration also initiates the file. To write the values to a stream, you can call the
fstream::write() method.
After calling the write() method, you can write the value of the variable to the
medium. Here is an example:
#include
<fstream>
#include
<iostream>
using
namespace
std; class
Student
{
public:
char FullName[40];
char
CompleteAddress[1
20]; char Gender;
double Age;
bool LivesInASingleParentHome;
};
int main()
{
Student one;
strcpy(one.FullName, "Ernestine Waller");
strcpy(one.CompleteAddress, "824 Larson Drv, Silver Spring, MD
20910"); one.Gender = 'F';
one.Age = 16.50;
one.LivesInASingleParentHome
= true; ofstream
ofs("fifthgrade.ros", ios::binary);
ofs.write((char *)&one,
sizeof(one)); return 0;
}
Reading From the Stream
Reading an object saved in binary format is as easy as writing it. To read the
value, call the ifstream::read() method. Here is an example:
#include
<fstream>
#include
<iostream>
using
namespace
std; class
Student
{
public:
char FullName[40];
char
CompleteAddress[1
20]; char Gender;
double Age;
bool LivesInASingleParentHome;
};
int main()
{
/*
Student one;
strcpy(one.FullName, "Ernestine Waller");
strcpy(one.CompleteAddress, "824 Larson Drv, Silver Spring, MD
20910"); one.Gender = 'F';
one.Age = 16.50;
one.LivesInASingleParentHom
e = true;
ofstream ofs("fifthgrade.ros",
ios::binary); ofs.write((char
*)&one, sizeof(one));
*/
Student two;
ifstream ifs("fifthgrade.ros",
ios::binary); ifs.read((char
*)&two, sizeof(two)); cout <<
"Student Information";
cout << "Student Name: " << two.FullName
<< endl; cout << "Address: " <<
two.CompleteAddress << endl; if(
two.Gender == 'f' || two.Gender == 'F' )
cout << "Gender: Female" << endl;
else if( two.Gender == 'm' ||
two.Gender == 'M' ) cout << "Gender:
Male" << endl;
else
cout << "Gender: Unknown"
<< endl; cout << "Age: " <<
two.Age << endl;
if( two.LivesInASingleParentHome == true )
cout << "Lives in a single parent home" << endl;
else
NAMESPACE:
§
The ANSI string class implements a first-class character string data type that avoids
many problems
§
associated with simple character arrays ("C-style strings"). You can define a string
object very
§
simply, as shown in the following example
#include <string>
using namespace std;
...
string first_name =
"Bjarne"; string last_name;
last_name = "Stroustrup";
string names = first_name + " " +
last_name; cout << names << endl;
names = last_name + ", " + first
" + first_name;
cout << names << endl;
Member functions
§
The string class defines many member functions. A few of the basic ones
are described below:
§
A string object may defined without an initializing value, in which case its initial
§
value is an empty string (zero length, no characters):
§
string str1;
§
A string object may also be initialized with
§
� a string expression:
§
string str2 = str1;
§
string str3 = str1 + str2;
§
string str4 (str2); // Alternate form
§
� a character string literal:
string str4 = "Hello there";
§
The standard template library (STL) contains
§
Containers
§
Algorithms
§
Iterators
§
A container is a way that stored data is organized in memory, for
example an array of elements.
§
Algorithms in the STL are procedures that are applied to containers to
process their data, for example search for an element in an array, or sort an array.
§
Iterators are a generalization of the concept of pointers, they point
to elements in a container, for example you can increment an iterator to
point to the next element in an array
UNIT V EXCEPTION HANDLING 9 Packages and Interfaces, Exception
handling, Multithreaded programming, Strings, Input/Output
The Add function adds the data to the end of the vector. The remove
function removes the first element. These functionalities make this C++ class
Template behave like a normal Queue. The print function prints all the data using
the iterator.
Full Program - C++ Class Templates:
//C++_Class_Templates.cpp
}
//Usage for C++
class templates
void main()
{
Templates:
Compiler generates classes for only the used types. If the template
is instantiated for int type, compiler generates only an int version for the c++
template class.
Templates reduce the effort on coding for different data types to a single
set of code.
Exeption Handling:
Exception handling is a mechanism that separates code that detects and
handles exceptional circumstances from the rest of your program. Note that an
exceptional circumstance is not necessarily an error.
When a function detects an exceptional situation, you represent this with
an object. This object is called an exception object. In order to deal with the
exceptional situation you throw the exception. This passes control, as well as the
exception, to a designated block of code in a direct or indirect caller of the
function that threw the exception. This block of code is called a handler. In a
handler, you specify the types of exceptions that it may process. The C++ run
time, together with the generated code, will pass control to the first appropriate
handler that is able to process the exception thrown. When this happens, an
exception is caught. A handler may rethrow an exception so it can be caught by
another handler.
The exception handling mechanism is made up of the following elements:
try blocks
catch blocks
throw expressions
Exception specifications (C++ only)
>>-catch--(--exception_declaration--)--{--statements--}--------><
A catch block can only catch accessible objects. The object caught must
have an accessible copy constructor.
throw expressions (C++ only)
You use a throw expression to indicate that your program has
encountered an exception. throw expression syntax
>>-throw--+-----------------------+----------------------------><
'-assignment_expression-'
void*
const void*
volatile void*
>>-throw--(--+--------------+--)-------------------------------><
'-type_id_list-'
Here‘s our square root program again, minus the try block in main():
#include "math.h" //
for sqrt() function
using namespace std;
A modular
square root
function double
MySqrt(double
dX)
{
// If the user entered a negative number, this is
an error condition if (dX < 0.0)
}
return sqrt(dX);
throw "Can not take sqrt of negative number"; // throw exception of type
char*
int main()
{
}
MySqrt() doesn‘t handle the exception, so the program stack unwinds and
control returns to main(). But there‘s no exception handler here either, so main()
terminates. At this point, we just terminated our application!
When main() terminates with an unhandled exception, the operating system will
generally notify you that an unhandled exception error has occurred. How it does
this depends on the operating system, but possibilities include printing an error
message, popping up an error dialog,
or simply crashing. Some OS‘s are less graceful than others.
Generally this is something you want to avoid
altogether!
Catch-all handlers
And now we find ourselves in a condundrum: functions can potentially throw
exceptions of any data type, and if an exception is not caught, it will propagate to
the top of your program and cause it to terminate. Since it‘s possible to call
functions without knowing how they are even
implemented, how can we possibly prevent this from happening?
Fortunately, C++ provides us with a mechanism to catch all types of
exceptions. This is known as a catch-all handler. A catch-all handler
works just like a normal catch block,
except that instead of using a specific type to catch, it uses the ellipses operator
(…) as the type to catch.