0% found this document useful (0 votes)
41 views101 pages

Oops

Uploaded by

ramrattan099
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
41 views101 pages

Oops

Uploaded by

ramrattan099
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 101

Object Oriented

Programming
Unit 1: Review of Object-
oriented Programming
1. Outline the essential steps involved in carrying out a
procedure-oriented programming study.

Answer: Programming practices have evolved considerably over the past few
decades. As more and more programmers gained experience problems unknown
hitherto, began to surface. The programming community became ever more
concerned about the philosophy that they adopt in programming and approaches
they practice in program development.
Factors like productivity, reliability, cost effectiveness, reusability etc. started to
become major concern. A lot of conscious efforts were put to understand these
problems and to seek possible solutions. This is precisely the reason why more
and more programming languages have been developed and still continue to
develop. In addition to this, approaches to program development have also been
under intense research thereby evolving different frame works. One such, and
probably the most popular one is object-oriented programming approach or
simply OOP.

2. Inheritance is the process by which objects of one class acquire


the properties of objects of another class. Analyze.
Answer:

Inheritance: Inheritance is the process by which objects of one class acquire


the properties of objects of another class. It supports the concept of hierarchical
classification.

For example, an manager class is a type of the class employee, which again is a
type of the class person as illustrated below.

The principle behind this sort of division is that each derived class shares
common characteristics with the class from which it is derived. The power of
inheritance lies in the fact that all common features of the subclasses can be
accumulated in the super class. In other words, a feature is placed in the higher
level of abstraction. Once this is done, such features can be inherited from the
parent class and used in the subclass directly. This
implies that if there are many abstract class definitions available, when a new
class is needed, it is possible that the new class is a specialization of one or
more of the existing classes.

In OOP, the concept of inheritance provides the idea of reusability. This means
that we can add additional features to an existing class without modifying it.
This is possible by deriving a new class from the existing one. The new class
will have the combined features of both the classes. Each subclass defines only
those features that are unique to it. In OOP, The concept of inheritance provides
the idea of reusability. This means that we can add additional features to an
existing class without modifying it. This is possible by deriving
a new class from the existing one. The new class will have the combined
features of both the classes.

3. Examine what are the benefits of OOP?


Answer: Benefits of OOP
Object-orientation contributes to the solution of many problems associated with
the development and quality of software products. The technology provides
greater programmer productivity, better quality of software and lesser
maintenance cost. The principle advantages are:

1. Through inheritance, we can eliminate redundant code and extend the use of
existing classes.
2. We can build programs from the standard working modules that
communicate with one another, rather than having to start writing the code from
scratch. This leads to saving of development time and higher productivity.
3. The principle of data hiding help the programmer to build secure programs
that cannot be invaded by code in other parts of the program.
4. It is possible to have multiple instances of an object to co-exist without any
interference.
5. It is possible to map objects in the problem domain to those objects in the
program.
6. It is easy partition the work in a project based on objects.
7. The data-centered design approach enables us to capture more details of a
model in implementable form.
8. Object oriented systems can be easily upgraded from small to large systems.
9. Message passing techniques for communication between objects makes the
interface descriptions with external systems much simpler.
10. Software complexity can be easily managed.
4. How are classes different from objects? Illustrate with suitable
examples.
Answer:

Classes: A class represents a set of related objects. The object has some
attributes, whose value consist much of the state of an object. The class of an
object defines what attributes an object has. The entire set of data and code of
an object can be made a user-defined data type with the help of a class.

Classes are user defined data types that behave like the built-in types of a
programming language. Classes have an interface that defines which part of an
object of a class can be accessed from outside and how. A class body that
implements the operations in the interface, and the instance variables that
contain the state of an object of that class.

The data and the operation of a class can be declared as one of the three
types:
(a) Public: These are declarations that are accessible from outside the class to
anyone who can access an object of this class.
(b) Protected: These are declarations that are accessible from outside the class
to anyone who can access an object of this class.
(c) Private: These are declarations that are accessible only from within the class
itself.

5. “Software engineers have developed a number of different ‘life


styles’ through which software passes”. Do you agree with your
statement? Why or why not?
Answer:
Software engineers have developed a number of different ‘life styles’ through
which software passes. In general these life styles are known as software
development life cycle or SDLC in short.

Following are the developmental phases of software:

 Study
The genesis of any software begins with the study of the problems, which it
intends to solve. Software cannot be envisaged unless there is a problem that it
must solve. Therefore, studying the problem in depth, understanding the true
nature of the problem and representing the problem in comprehensible manner
is what necessitates inclusion of this phase.
 Analysis
It is a detailed study of the various operations performed by the proposed
software. A key question that is considered in this phase of development is –
What must be done to solve the problem? One aspect of analysis is defining the
boundaries or interface of the software.
During analysis, data are collected in available files, decision points, and
transactions handled by the present system. Bias in data collection and
interpretation can be fatal to the developmental efforts.
Once analysis is completed the analyst has a firm understanding of what is to be
done. The next step is to decide how the problem might be solved. Thus, in the
software systems design, we move from the logical to the physical aspects of
the life cycle.

 Design
The most creative and challenging phase of software life cycle is design. The
term design describes both a final software system and a process by which it is
developed. It refers to the technical specifications (analogous to the engineer’s
blueprints) that will be applied in implementing the software system. It also
includes testing the software. The key question around which this phase
revolves is – How should the problem be solved?
The first step is to determine how the output is to be produced and in what
format. Samples of the output (and input) are outlined.
Second, input data and master files (data base) have to be designed to generate
the required output. The operational (processing) phase are handled through
program construction and testing, including a list of the programs needed to
meet the software objectives and complete documentation.
Finally, details related to justification of the system and an estimate of the
impact of the software on the user are documented and evaluated before it is
implemented.

 Implementation
This phase is primarily concerned with coding the software design into an
appropriate programming language; testing the programs and installing the
software. User training, site preparation, and data migration are other important
issues in this phase.

 Maintenance
Change is inevitable. Software serving the users’ needs in the past may become
less useful or sometimes useless in the changed environment. Users’ priorities,
changes in organizational
requirements, or environmental factors may call for software enhancements. A
bank, for instance, may decided to increase its service charges for checking
accounts from ` 3.00 to ` 450 for a minimum balance of ` 3,000. In this phase
the software is continuously evaluated and modified to suit the changes as they
occur.

7. The technology provides greater programmer productivity,


better quality of software and lesser maintenance cost. Explain
how?
Answer: The technology provides greater programmer productivity,
better quality of software and lesser maintenance cost. The principle advantages
are:
1. Through inheritance, we can eliminate redundant code and extend the use of
existing classes.
2. We can build programs from the standard working modules that
communicate with one another, rather than having to start writing the code from
scratch. This leads to saving of development time and higher productivity.
3. The principle of data hiding help the programmer to build secure programs
that cannot be invaded by code in other parts of the program.
4. It is possible to have multiple instances of an object to co-exist without any
interference.
5. It is possible to map objects in the problem domain to those objects in the
program.
6. It is easy partition the work in a project based on objects.
7. The data-centered design approach enables us to capture more details of a
model in implementable form.
8. Object oriented systems can be easily upgraded from small to large systems.
9. Message passing techniques for communication between objects makes the
interface descriptions with external systems much simpler.
10. Software complexity can be easily managed.

8. Scrutinize the meaning of dynamic binding with an example.


Answer:
Dynamic Binding: Binding refers to the linking of a procedure call to the code
to be executed in response to the call. Dynamic binding means that the code
associated with a given procedure call is not known until the time of call at run-
time. This is associated with polymorphism and inheritance. A function call
associated with a polymorphic reference depends on the dynamic type of that
reference. For example in the above figure, by inheritance, every object will
have this procedure. Its algorithm is, however, unique to each object so the
procedure will be redefined in each class that defines the objects. At
run-time, the code matching the object under reference will be called.

9. Make distinctions between data abstraction and data


encapsulation. Give examples.

Answer:

1. Dynamic Binding: Binding refers to the linking of a procedure call to the


code to be executed in response to the call. Dynamic binding means that the
code associated with a given procedure call is not known until the time of call at
run-time. This is associated with polymorphism and inheritance. A function call
associated with a polymorphic reference depends on the dynamic type of that
reference. For example in the above figure, by inheritance, every object will
have this procedure. Its algorithm is, however, unique to each object so the
procedure will be redefined in each class that defines the objects. At
run-time, the code matching the object under reference will be called.

2. Data Encapsulation: The wrapping up to data and functions into a single


unit (class) is known as encapsulation. Data encapsulation is the most striking
feature of a class. The data is not accessible to the outside world and only those
functions that are wrapped in the class can access it. These functions provide the
interface between the object’s data and the program. This insulation of the data
from direct access by the program is called data hiding.

10. Compare what you look for in the problem description when
applying object-oriented approach in contrast to the procedural
approach. Illustrate with some practical examples.
Answer: Object-oriented approach offers perhaps the most logical description
of the real world. Therefore, it can be applied in almost all the situations of
problem solving. Because of its effectiveness in problem solving and
programming, OOP has been adopted all over the software industry. The
existing systems are being migrated to OOP.
One important aspect of OOP that is particularly beneficial is the framework,
which encompasses all the phases of a system development. Thus, OOA (Object
Oriented Analysis), OOD (Object Oriented Design), OOT (Object Oriented
Testing) etc. are far more suitable tools than their non-object-oriented
counterparts. Above all, the reusability feature of the Object Oriented approach
has facilitated the rapid growth of software both in variety and scope.
Unit 2: Beginning of OOP Language

Review of Tokens
As we know, the smallest individual units in a program are known as tokens. C++ has the
following tokens:
1. Keywords
2. Identifiers
3. Constants
4. Strings
5. Operators

Keywords
The keywords implement specific C++ language features. They are explicitly reserved
identifiers and cannot be used as names for the program variables or other user-defined
program elements.

Identifiers
Identifiers refer to the names of variables, functions, arrays, classes, etc., created by the
programmer. They are the fundamental requirement of any language. Each language has its
own rules for naming these identifiers.

Operators

An operator is a symbol that tells the compiler to perform specific mathematical or logical
manipulations. C++ is rich in built-in operators and provide the following types of operators

 Arithmetic Operators
 Relational Operators
 Logical Operators
 Bitwise Operators
 Assignment Operators

 Assignment operator (=)


The assignment operator assigns a value to a variable.

x = 5;

This statement assigns the integer value 5 to the variable x. The assignment operation always
takes place from right to left, and never the other way around:
x = y;

This statement assigns to variable x the value contained in variable y. The value of x at the
moment this statement is executed is lost and replaced by the value of y.

 Arithmetic operators ( +, -, *, /, % )
The five arithmetical operations supported by C++ are:

operator description

+ addition

- subtraction

* multiplication

/ division

% modulo

Operations of addition, subtraction, multiplication and division correspond literally to their


respective mathematical operators. The last one, modulo operator, represented by a
percentage sign (%), gives the remainder of a division of two values. For example:

x = 11 % 3;

results in variable x containing the value 2, since dividing 11 by 3 results in 3, with a


remainder of 2.

 Compound assignment (+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=)
Compound assignment operators modify the current value of a variable by performing an
operation on it. They are equivalent to assigning the result of an operation to the first
operand:

expression equivalent to...

y += x; y = y + x;

x -= 5; x = x - 5;
x /= y; x = x / y;

price *= units + 1; price = price * (units+1);

 Increment and decrement (++, --)


Some expression can be shortened even more: the increase operator (++) and the decrease
operator (--) increase or reduce by one the value stored in a variable. They are equivalent to
+=1 and to -=1, respectively. Thus:

1 ++x;
2 x+=1;
3 x=x+1;

are all equivalent in its functionality; the three of them increase by one the value of x.

 Relational and comparison operators ( ==, !=, >, <, >=, <= )
Two expressions can be compared using relational and equality operators. For example, to
know if two values are equal or if one is greater than the other.

The result of such an operation is either true or false (i.e., a Boolean value).

The relational operators in C++ are:

operator description

== Equal to

!= Not equal to

< Less than

> Greater than

<= Less than or equal to

>= Greater than or equal to

Here there are some examples:

1 (7 == 5) // evaluates to false
2 (5 > 4) // evaluates to true
3 (3 != 2) // evaluates to true
4 (6 >= 6) // evaluates to true
5 (5 < 5) // evaluates to false

 Logical operators ( !, &&, || )


The operator ! is the C++ operator for the Boolean operation NOT. It has only one operand,
to its right, and inverts it, producing false if its operand is true, and true if its operand is false.
Basically, it returns the opposite Boolean value of evaluating its operand. For example:

1 !(5 == 5) // evaluates to false because the expression at its right (5 == 5) is true


2 !(6 <= 4) // evaluates to true because (6 <= 4) would be false
3 !true // evaluates to false
4 !false // evaluates to true

 Conditional ternary operator ( ? )


The conditional operator evaluates an expression, returning one value if that expression
evaluates to true, and a different one if the expression evaluates as false. Its syntax is:

condition ? result1 : result2

If condition is true, the entire expression evaluates to result1, and otherwise to result2.

1 7==5 ? 4 : 3 // evaluates to 3, since 7 is not equal to 5.


2 7==5+2 ? 4 : 3 // evaluates to 4, since 7 is equal to 5+2.
3 5>3 ? a : b // evaluates to the value of a, since 5 is greater than 3.
4 a>b ? a : b // evaluates to whichever is greater, a or b.

Comma operator ( , )
The comma operator (,) is used to separate two or more expressions that are included where
only one expression is expected. When the set of expressions has to be evaluated for a value,
only the right-most expression is considered.

For example, the following code:

a = (b=3, b+2);

would first assign the value 3 to b, and then assign b+2 to variable a. So, at the end, variable a
would contain the value 5 while variable b would contain value 3.
 Bitwise operators ( &, |, ^, ~, <<, >> )
Bitwise operators modify variables considering the bit patterns that represent the values they
store.

operator asm equivalent description

& AND Bitwise AND

| OR Bitwise inclusive OR

^ XOR Bitwise exclusive OR

~ NOT Unary complement (bit inversion)

<< SHL Shift bits left

>> SHR Shift bits right

 sizeof
This operator accepts one parameter, which can be either a type or a variable, and returns the
size in bytes of that type or object:

x = sizeof (char);

Here, x is assigned the value 1, because char is a type with a size of one byte.

Control Structures:

Conditional structure: if and else


The if keyword is used to execute a statement or block only if a condition is fulfilled. Its form is:

if (condition) statement

Where condition is the expression that is being evaluated. If this condition is true, statement is
executed. If it is false, statement is ignored (not executed) and the program continues right after
this conditional structure.
For example, the following code fragment prints x is 100 only if the value stored in the x variable
is indeed 100:

1 if (x == 100)
2 cout << "x is 100";

If we want more than a single statement to be executed in case that the condition is true we can
specify a block using braces { }:

1 if (x == 100)
2{
3 cout << "x is ";
4 cout << x;
5}

We can additionally specify what we want to happen if the condition is not fulfilled by using the
keyword else. Its form used in conjunction with if is:

if (condition) statement1 else statement2

For example:

1 if (x == 100)
2 cout << "x is 100";
3 else
4 cout << "x is not 100";

 Iteration structures (loops)

Loops have as purpose to repeat a statement a certain number of times or while a condition is
fulfilled.

 The while loop


Its format is:

while (expression) statement

and its functionality is simply to repeat statement while the condition set in expression is true.
For example, we are going to make a program to countdown using a while-loop:

1 // custom countdown using while


Enter the starting number > 8
2
8, 7, 6, 5, 4, 3, 2, 1, FIRE!
3 #include <iostream>
4 using namespace std;
5
6 int main ()
7 {
8 int n;
9 cout << "Enter the starting number > ";
10 cin >> n;
11
12 while (n>0) {
13 cout << n << ", ";
14 --n;
15 }
16
17 cout << "FIRE!\n";
18 return 0;
19 }

 The do-while loop

Its format is:

do statement while (condition);

Its functionality is exactly the same as the while loop, except that condition in the do-while
loop is evaluated after the execution of statement instead of before, granting at least one
execution of statement even if condition is never fulfilled. For example, the following
example program echoes any number you enter until you enter 0.

1 // number echoer
2
3 #include <iostream>
4 using namespace std;
5
Enter number (0 to end): 12345
6 int main ()
You entered: 12345
7 {
Enter number (0 to end): 160277
8 unsigned long n;
You entered: 160277
9 do {
Enter number (0 to end): 0
10 cout << "Enter number (0 to end): ";
You entered: 0
11 cin >> n;
12 cout << "You entered: " << n << "\n";
13 } while (n != 0);
14 return 0;
15 }
 The for loop

Its format is:

for (initialization; condition; increase) statement;

and its main function is to repeat statement while condition remains true, like the while loop.
But in addition, the for loop provides specific locations to contain an initialization statement
and an increase statement. So this loop is specially designed to perform a repetitive action
with a counter which is initialized and increased on each iteration.

Here is an example of countdown using a for loop:

1 // countdown using a for loop


2 #include <iostream>
3 using namespace std;
4 int main ()
5 {
6 for (int n=10; n>0; n--) { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE!
7 cout << n << ", ";
8 }
9 cout << "FIRE!\n";
10 return 0;
11 }

Memory management operators

 Arrays can be used to store multiple homogenous data but there are serious
drawbacks of using arrays.
 Programmer should allocate the memory of an array when they declare it but most of
time, the exact memory needed cannot be determined until runtime.
 The best thing to do in this situation is to declare the array with maximum possible
memory required (declare array with maximum possible size expected) but this
wastes memory.
 So, To avoid wastage of memory, you can dynamically allocate the memory required
during runtime using new and delete operator.
What are memory management operators?
There are two types of memory management operators in C++:

 new
 delete

These two memory management operators are used for allocating and freeing memory blocks
in efficient and convenient ways.

New operator:

 The new operator in C++ is used for dynamic storage allocation. This operator can be
used to create object of any type.

General syntax of new operator in C++:


pointer variable = new datatype;

 In the above statement, new is a keyword and the pointer variable is a variable of type
datatype.

For example:
1. int *a = new int;

2. *a = 20;
or
3. int *a = new int(20);

 In the above example, the new operator allocates sufficient memory to hold the object
of datatype int and returns a pointer to its starting point.
 the pointer variable a holds the address of memory space allocated.

delete operator:

 The delete operator in C++ is used for releasing memory space when the object is no
longer needed.
 Once a new operator is used, it is efficient to use the corresponding delete operator for
release of memory.

General syntax of delete operator in C++:


delete pointer variable;
Example:
#include <iostream>

void main()
{
//Allocates using new operator memory space in memory for storing a integer datatype
int *a= new int;
*a=100;
cout << " The Output is:a= " << *a;
//Memory Released using delete operator
delete a;
}

Output:

The Output is:a=100


Unit 3: Review of Functions

1. What is function prototyping? Why is it necessary? When is it


not necessary?
Answer: Function Prototyping

Prototype of a function is the function without its body. The C++ compiler
needs to about a
function before you call it, and you can let the compiler know about a function
is two ways – by defining it before you call it or by specifying the function
prototypes before you call it. Many programmers prefer a ‘Top-Down’
approach in which main() appears ahead the user-defined function definition. In
such approach, function access will precede function definition. To overcome
this, we use the function prototypes or we declare the function.

Function-prototype are usually written at the beginning of a program, ahead of


any programmer-defined functions including main (). In general, function
prototype is written as:
Return-type name (type 1 arg. 1, type 2 arg. 2, ….. type n arg. n);
Where return-type represents the data type of the value returned by the function,
name represents the function name, type 1, type 2 …. type n represents the data-
type of arguments art. 1, arg. 2 … arg n. The function prototypes resemble first
line to function definition, though it ends with the semicolon. Within the
function declaration, the names of arguments are optional but data-types are
necessary for eq. Int count (int);

The code snippet given below will cause compilation error because the main
function does not know about the called function one().
void main()
{

one(); //incorrect!! No function prototype available for one()

}
void one()
{
//function definition
}
To resolve this problem you should define the function before it is called as
shown below:
void one ()
{
//function definition
}
void main()
{

one(); //Correct!! Function one is defined before calling

}
Another elegant alternative to this problem is to include a function prototype
before it called no matter where the function has been actually defined as shown
below:

void one (void); //prototype of function one ()


void main()
{

one(); //Correct!! Function one is defined before calling

}
void one ()
{
//function definition
}

2. What is purpose of inline function?


Answer: C++ provides facility of inline function, which is designed to speed
up the program execution.

This is done by the C++ compiler, which incorporates it into a program.


When any program is compiled the output of compilation is a set of machine
language instructions, which is in executable program. When a program is run,
this complied copy of program is put into memory. Each instruction gets a
memory address, which is used to refer that instruction. These instructions are
executed as per the logic in the program. Instructions are executed step by step
unless there are any loop or branching instructions. When there is branch or
jump instruction, some instructions are skipped and forward or backward jump
is made.

In normal function call, the control of execution is transferred to the location


where the function is loaded in memory that is the starting executable
instruction of the function. When all the instructions of the function are
executed the control returns back to main program from where left.

Now the next instruction in the main program will get executed. Jumping back
and forth keeping track of where to jump means that there is an overhead in
elapsed time to functions. When the function is declared inline the compiler
replaces the function call with the corresponding function code. As a result the
program does not have to spend time to jump to another location to execute the
function and then come back. But there is a memory overhead. If the function is
called n times in the program then it is copied n times making the program code
or in particular executable code large. If the value of n is large, there is a lot of
memory overhead.

3. Differentiate between the following:


(a) void main()
(b) int main()
(c) int main (int argn, char argv[])

Answer: You must be knowing that main() function defines life of a c


program. It means any c program starts from main () function and also ends
with main () function, except when program is terminated through exit ()
statement. The main() function is called by system, when we execute the
program. All other functions are called with in main () function by programmer.

There is not any significance difference between void main () and int main ()
meaning wise but syntactically when you use int main () then you have to return
some integer value at end (as return type is int) while using void main () there
is no such need (as return type is void).

Thus in both cases above it is like normal function except it is called by system.

Coming to int main (int argc, char *argv[]), this syntax for main function is
used when we want to pass parameters to main function (called command line
arguments).
In the above signature of main, first parameter (which must be int) contains no
of arguments and second parameter (which must be string array) contains the
argument values (which are strings). The first argument is always the program
name and subsequent are actual parameters.

4. Write a program that uses overloaded member functions for


converting temperature from Celsius to Kelvin scale?
Answer:

#include <iostream>
using namespace std;

int main ()
{
float kel, cel;
cout << "\n\n Convert temperature in Celsius to Kelvin :\n";
cout << " \n";
cout << " Input the temperature in Celsius : ";
cin >> cel;
kel = cel + 273.15;
cout << " The temperature in Celsius : " << cel << endl;
cout << " The temperature in Kelvin : " << kel << endl;
cout << endl;
return 0;
}

Sample Output:

Convert temperature in Celsius to Kelvin:

Input the temperature in Celsius: 26.85


The temperature in Celsius: 26.85
The temperature in Kelvin: 300
5. Prototype of a function is the function without its body.
Analyze and explain with an example.
Answer:

Prototype of a function is the function without its body. The C++ compiler
needs to about a function before you call it, and you can let the compiler know
about a function is two ways – by defining it before you call it or by specifying
the function prototypes before you call it. Many programmers prefer a ‘Top-
Down’ approach in which main() appears ahead the user-defined function
definition. In such approach, function access will precede function definition.
To overcome this, we use the function prototypes or we declare the function.
Function-prototype are usually written at the beginning of a program, ahead of
any programmer-defined functions including main (). In general, function
prototype is written as:

Return-type name (type 1 arg. 1, type 2 arg. 2, ….. type n arg. n);

Where return-type represents the data type of the value returned by the function,
name represents the function name, type 1, type 2 …. type n represents the data-
type of arguments art. 1, arg. 2 … arg n. The function prototypes resemble first
line to function definition, though it ends with the semicolon. Within the
function declaration, the names of arguments are optional but data-types are
necessary for eq. Int count (int);

6. How can inline functions help with the tradeoff of safety vs.
speed?
Answer:
C++ provides facility of inline function, which is designed to speed up the
program execution. This is done by the C++ compiler, which incorporates it into
a program.

When any program is compiled the output of compilation is a set of machine


language instructions, which is in executable program. When a program is run,
this complied copy of program is put into memory. Each instruction gets a
memory address, which is used to refer that instruction. These instructions are
executed as per the logic in the program. Instructions are executed step by step
unless there are any loop or branching instructions. When there is branch or
jump instruction, some instructions are skipped and forward or backward jump
is made.

In normal function call, the control of execution is transferred to the location


where the function is loaded in memory that is the starting executable
instruction of the function. When all the instructions of the function are
executed the control returns back to main program from where left.

Now the next instruction in the main program will get executed. Jumping back
and forth keeping track of where to jump means that there is an overhead in
elapsed time to functions. When the function is declared inline the compiler
replaces the function call with the corresponding function code. As a result the
program does not have to spend time to jump to another location to execute the
function and then come back. But there is a memory overhead. If the function is
called n times in the program then it is copied n times making the program code
or in particular executable code large. If the value of n is large, there is a lot of
memory overhead.
Unit 4: Classes and Objects
1. Define class. What is the difference between structures and
classes in C++?
Answer: Specifying a Class

A class is a way to bind the data and its associated functions together. It allows
the data (and functions) to be hidden, if necessary, from external use. When
defining a class, we are creating a new abstract data-type that can be treated like
any other built-in data-type.

Generally, a class specification has two parts:


1. Class declaration
2. Class function definitions

The class declaration describes the type and scope of its members. The class
function definitions describe how the class functions are implemented. The
general form of a class declaration is:

class <class_name>
{
private:
variables declaration;
function declarations;
public:
variable declaration;
function declarations;
};

A) Class
1. A class in C++ can be defined as a collection of related variables and
functions encapsulated in a single structure.
2. A class in C++ is just an extension of a structure used in the C language.
It is a user defined data type. It actually binds the data and its related
functions in one unit.
3. Keyword for the declaration: Class
4. Default access specifier: Private
5. Purpose: Data abstraction and further inheritance
6. Type: Reference
7. Usage: Generally used for large amounts of data.
8. Its object is created on the heap memory.
9. The member variable of class can be initialized directly.
10. It can have all the types of constructor and destructor.

B) Structure
1. A structure in C++ can be referred to as an user defined data type
possessing its own operations.
2. A structure and a class in C language differs a lot as a structure has
limited functionality and features as compared to a class.
3. Keyword for the declaration: Struct
4. Default access specifier: Public
5. Purpose: Generally, grouping of data
6. Type: Value
7. Usage: Generally used for smaller amounts of data.
8. Its object is created on the stack memory.
9. The member variable of structure cannot be initialized directly.
10. It can have only parameterized constructor.

So, this were some differences between Class and Structure.

2. How can you pass an object of a C++ class to/from a C


function?
Answer:

Here's an example (for info on extern "C", see the previous two FAQs).

Fred.h:

/* This header can be read by both C and C++ compilers */


#ifndef FRED_H
#define FRED_H

#ifdef cplusplus
class Fred {
public:
Fred();
void wilma(int);
private:
int a_;
};
#else
typedef
struct Fred
Fred;
#endif

#ifdef cplusplus
extern "C" {
#endif

#if defined( STDC ) || defined( cplusplus)


extern void c_function(Fred*); /* ANSI C prototypes */
extern Fred* cplusplus_callback_function(Fred*);
#else
extern void c_function(); /* K&R style */
extern Fred* cplusplus_callback_function();
#endif

#ifdef cplusplus
}
#endif

#endif /*FRED_H*/
Fred.cpp:
// This is C++ code

#include "Fred.h"

Fred::Fred() : a_(0) { }

void Fred::wilma(int a) { }

Fred* cplusplus_callback_function(Fred* fred)


{
fred->wilma(123);
return fred;
}
main.cpp:
// This is C++ code

#include "Fred.h"

int main()
{
Fred fred;
c_function(&fred);
...
}
c-function.c:
/* This is C code */

#include "Fred.h"

void c_function(Fred* fred)


{
cplusplus_callback_function(fred);
}
Unlike your C++ code, your C code will not be able to tell that two pointers
point at the same object unless the pointers are exactly the same type. For
example, in C++ it is easy to check if a Derived* called dp points to the same
object as is pointed to by a Base* called bp: just say if (dp == bp) .....The
C++ compiler automatically converts both pointers to the same type, in this case
to Base*, then compares them. Depending on the C++ compiler's
implementation details, this conversion sometimes changes the bits of a
pointer's value.

The point is simple: your C compiler will not know how to do that pointer
conversion, so the conversion from Derived* to Base*, for example, must take
place in code compiled with a C++ compiler, not in code compiled with a C
compiler.

NOTE: you must be especially careful when converting both to void* since that
conversion will not allow either the C or C++ compiler to do the proper pointer
adjustments! The comparison (x == y) might be false even if (b == d) is
true:

void f(Base* b, Derived* d)


{
if (b == d) { Validly compares a Base* to a Derived*
...
}

void* x = b;
void* y = d;
if (x == y) { BAD FORM! DO NOT DO THIS!
...
}
}
As stated above, the above pointer conversions will typically happen with
multiple and/or virtual inheritance, but please do not look at that as an
exhaustive list of the only times when the pointer conversions will happen.
You have been warned.

If you really want to use void* pointers, here is the safe way to do it:
void f(Base* b, Derived* d)
{
void* x = b;
void* y = static_cast<Base*>(d); ← If conversion is needed, it
will happen in the static_cast<>
if (x == y) { Validly compares a Base* to a Derived*
...
}
}

3. What’s the difference between the keywords struct and class?


Answer:

Key Difference: C++ is an object oriented language that mainly focuses on


objects. A class in C++ can be defined as a collection of related variables and
functions encapsulated in a single structure. Instances of the class are termed as
objects. A structure in C++ can be referred to as an user defined data type
possessing its own operations. Unlike in the C language, they both are quite
similar in C++. The main difference that exists between them is regarding the
access modifier; the members of a class are private by default, whereas
members of a struct are public by default.

A class in C++ is just an extension of a structure used in the C language. It is a


user defined data type. It actually binds the data and its related functions in
one unit. A structure and a class in C language differs a lot as a structure has
limited functionality and features as compared to a class. On the other hand,
structure and class in C++ are quite similar. The main difference arises due to
the fact that by default, all the members of a class are private, whereas by
default all the members of a structure are public.

Structure is also a user defined data type with a certain template. It is generally
used for grouping of logically related data items. After the creation of
a structure, the variables pertaining to the type of structure can be defined and
used. A structure is used to represent a record. In C++, a structure can have both
data members and functions as classes. Many people find it difficult to
differenciate between a class and a structure. Technically they both are regarded
as the same in C++.

Comparison between Class and Structure in C++:

Class Structure
A class in C++ can be A structure can be
defined as a collection of referred to as a user
Definition related variables and defined data type
functions encapsulated in possessing its own
a single structure. operations.
Keyword for the
Class Struct
declaration
Default access specifier Private Public
class myclass struct myclass

{ {

private: private:

int data; int data;


Example
public: public:

myclass(int data_): myclass(int data_):

data(data_) data(data_)
{} {}

virtual void foo()=0; virtual void foo()=0;

virtual ~class() virtual ~class()

{} {}

}; };
Data abstraction and Generally, grouping of
Purpose
further inheritance data
Type Reference Value
Generally used for large Generally used for
Usage
amounts of data. smaller amounts of data.

4. How does C++ help with the tradeoff of safety vs. usability?
Answer:

(Note: Here is a discussion on this topic given below):

FAQ: In C, stuff is either stored in structs (safety problem - no encapsulation),


or it is declared static at the file implementing an interface (usability problem -
there is no way to have many instances of that data).

With C++ classes, you can have many instances of the data (many objects) and
encapsulation (non-public members).

FQA: This is wildly wrong, and the chances that the FAQ author didn't know it
are extremely low. That's because you can't use FILE* from <stdio.h> or
HWND from <windows.h> or in fact any widely used and/or decent C library
without noticing that the FAQ's claim is wrong.

When you need multiple instances and encapsulation in C, you use a forward
declaration of a struct in the header file, and define it in the implementation file.
That's actually better encapsulation than C++ classes - there's still no run-time
encapsulation (memory can be accidentally/maliciously overwritten), but at
least there's compile-time encapsulation (you don't have to recompile the code
using the interface when you change the implementation).

The fact that a crude C technique for approximating classes is better than the
support for classes built into the C++ language is really shameful. Apparently so
shameful that the FAQ had to distort the facts in an attempt to save face (or else
the readers would wonder whether there's any point to C++ classes at all). The
FQA hereby declares that it will not go down this path. Therefore, we have to
mention this: the forward declaration basically makes it impossible for the
calling code to reserve space for the object at compile time. This means that a
struct declared in a header file or a C++ class can sometimes be allocated more
efficiently than a forward-declared struct. However, this is really about a
different tradeoff - safety vs. efficiency, and there's no escape from this tradeoff.
Either the caller knows about the details such as the size of an object at compile
time - which breaks compile-time encapsulation - or it doesn't, so it can't handle
the allocation.

5. “The main advantage of using a static member is to declare the


global data which should be updated while the program lives in
memory”. Justify your statement.
Answer:
Accessing a Member of Class:
Member data items of a class can be static. Static data members are data objects
that are common to all objects of a class. They exist only once in all objects of
this class. The static members are used when the information is to be shared.
They can be public or private data. The main advantage of using a static
member is to declare the global data which should be updated while the
program lives in memory. When a static member is declared private, the non-
member functions cannot access these members. But a public static member can
be accessed by any member of the class. The static data member should be
created and initialized before the main function control block begins.

Example: Consider the class account as follows:


class account
{
private:
int acc _no;
static int balance; //static data declaration
public:
void disp (int acc _no);
void getinfo ( );
};
The static variable balance is initialized outside main () as follows:
int account::balance = 0; //static data definition
Consider the following Program which demonstrates the use of static data
member count. The
variable count is declared static in the class but initialized to 0 outside the class.
#include <iostream.h>
#include <conio.h>
class counter
{
private:
static int count;
public:
void disp ();
};
int counter::count = 0;
void counter::disp()
{
count++
cout << “The present value of count is “ << count << “\n”;
}
main()
{
counter cntl ;
for(int i=0; i<5; i++)
cnt1.disp();
getche();

}
You should get the following output from this program.
The present value of count is 1
The present value of count is 2
The present value of count is 3
The present value of count is 4
The present value of count is 5

6. Write a program to print the score board of a cricket match in


real time. The display should contain the batsman’s name, runs
scored, indication if out, mode by which out, bowler’s score (overs
played, maiden overs, runs given, wickets taken). As and when a
ball is thrown, the score should be updated.
Answer:
#include<iostream.h>
#include<conio.h>
#include<stdio.h>

struct batting
{
char batsman[20];
int run;
boolean out;
int tot_run;
int overs;
int total_over;
int extra;
};

struct bowling
{
char bowler[20];
int overs;
int maiden_overs;
int runs;
int wicket;
};

void main()
{
batting bat_team[12];

bowling bo_team[12];
cout<<"\n Enter records of batting team :\n\n";
for(int i = o; i < 12 ; i++)
{
cout<<"\n Enter bat's man name :";
gets(bat_team[i].batsman);
cout<<"\n Enter run scored :";
cin>>bat_team[i].run;
cout<<"\n Type 0 NOT-OUT , Type 1 if OUT :";
cin>>bat_team[i].out;
cout<<"\n Enter total run :";
cin>>bat_team[i].total_run;
cout<<"\n Enter no. of overs played :";
cin>>bat_team[i].overs;
cout<<"\n Enter total over:";
cin>>bat_team[i].total_over;
cout<<"\n Extra ?";
cin>>bat_team[i].extra;
}

cout<<"\n Enter records of bowling team :\n\n";

for( i = o; i < 12 ; i++)


{
cout<<"\n Enter bowler's name :";
gets(bo_team[i].bowler);
cout<<"\n Enter overs bowled :";
cin>>bo_team[i].overs;
cout<<"\n Enter maiden overs :";
cin>>bo_team[i].maiden_overs;
cout<<"\n Enter runs :";
cin>>bo_team[i].runs;
cout<<"\n Enter wicked taken:";
cin>>bo_team[i].wicket;
}
char ch;
int n;

do
{
clrscr();

cout<<"\n Enter 1 to view batting team information:";

cout<<"\n Enter 2 to view bowling team information:";

cout<<"\n Enter your choice :";

cin>>n;

switch(n)

case 1:

cout<<"\n ************* BATTING TEAM *************\n";

cout<<"\n Name \t RUN-Scored Out Total-run Over's-played Total-Overs Extra


";

for( i = o; i < 12 ; i++)


{

cout<<"\n"<< bat_team[i].batsman <<"\t"<< bat_team[i].run<<" ";

if(bat_team.out)

cout<<"OUT";
else
cout<<"NOT-OUT";

cout<< " " << bat_team[i].total_run<< " " << bat_team[i].overs << " " <<
bat_team[i].total_over<< " "<< bat_team[i].extra;
}

break;

case 2:

cout<< "\n ************* BOWLING TEAM *************\n";


cout<< "\n Name \t Overs_bowled Maiden-Overs Runs-Given Wicket-Taken ";

for( i = o; i < 12 ; i++)

{
cout<< "\n"<< bo_team[i].bowler<< "\t"<< bo_team[i].overs<< " ";
cout<< " "<< bo_team[i].maiden_overs<< " "<< bo_team[i].runs<< " "<<
bo_team[i].wicket<<" ";
}
break;
default:

cout<< "\n Wrong choice.";

cout<<"\n Do you continue (y/n);

cin>>ch;

}while(ch=='y' | | ch == 'Y');
getch();
}

7. If a member of a class is public, it can be accessed by an


external function including a derived class. Explain with an
example.
Answer:

The Protected Access Specifier


If a member of a class is public, it can be accessed by an external function
including a derived class. If a member of a class is private, it cannot be accessed
by an external function; even a derived class cannot access it.
The question is, should a derived class not really be able to access a private
member of its base class (since the derived class and base class are related)?
Well, to solve this problem you have another access specifier called, protected.
If a member of a class is protected, it can be accessed by a derived class, but it
cannot be accessed by an external function. It can also be accessed by members
within the class. The following code illustrates how a derived class can access a
protected member of a base class:

#include <iostream>
using namespace std;
class Calculator
{
protected:
int num1;
int num2;
};
class ChildCalculator: public Calculator
{
public:
int add()
num1 = 2;
num2 = 3;
int sum = num1 + num2;
return sum;
}
};
int main()
{
ChildCalculator myChildObj;
int result = myChildObj.add();
cout << result;
return 0;
}

The base class has just two properties and no method; these properties are
protected. The derived class has one method and no property. Inside the derived
class, the protected properties of the base class are used as identifiers.
Generally, when a derived class is using a member of a base class, it is a method
of the derived class that is using the member, as in this example. The above
code is OK.

8. Write a program in which a class has one private member


(properties) and two public member (method).
Answer:

# include <iostream.h>

# include <conio.h>
class student

private:

int rn;

float fees;

void read()

rn=12;

fees=145.10;

public:

void show ()

read();

cout<<"\n Rollno = "<<rn;

cout<<"\n Fees = "<<fees;

}
};

void main ( )

clrscr ( );

student st;

// st.read ( ); // not accessible

st.show ( );

getch();

}
Unit 5: Static Members
1. Why did C++ add the class keyword?

Answer: The Class Keyword

Syntax for the class keyword is as follows.


class class_name
{
// access control keywords here
// class variables and methods declared here
};

You use the class keyword to declare new types. A class is a collection of class
member data, which are variables of various types, including other classes. The
class also contains class functions—or methods—which are functions used to
manipulate the data in the class and to perform other services for the class. You
define objects of the new type in much the same way in which you define any
variable. State the type (class) and then the variable name (the object). You
access the class members and functions by using the dot (.) operator. You use
access control keywords to declare sections of the class as public or private. The
default for access control is private. Each keyword changes the access control
from that point on to the end of the class or until the next access control
keyword. Class declarations end with a closing brace and a semicolon.

2. The const keyword specifies that the values of the variable will
not change throughout the program. Analyze.
Answer:

The Const Keyword

The keyword, const (for constant), precedes the data type of a variable.

Syntax
const <data type> <name of variable> = <value>;

Example:
const float g = 9.8;
cout << “The acceleration due to gravity is” << g << “m/s2”;
g=g+4; // ERROR!! Const variables cannot be modified.
The const keyword specifies that the values of the variable will not change
throughout the
program. This prevents the programmer from changing the value of variable,
like the one in the example given above. If the keyword, const, has been used
while defining the variable, the compiler will report an error if the programmer
tries to modify it.
3. “The static keyword can be used to declare variables, functions,
class data members and class functions”. Justify with an example.
Answer:

Static member:

The static keyword can be used to declare variables, functions, class data
members and class functions.

By default, an object or variable that is defined outside all blocks has static
duration and external linkage. Static duration means that the object or variable
is allocated when the program starts and is deallocated when the program ends.
External linkage means that the name of the variable is visible from outside the
file in which the variable is declared. Conversely, internal linkage means that
the name is not visible outside the file in which the variable is declared.

The static keyword can be used in the following situations:

•When we declare a variable or function at file scope (global and/or namespace


scope), the static keyword specifies that the variable or function has internal
linkage. When you declare a variable, the variable has static duration and the
compiler initializes it to 0 unless you specify another value.

•When we declare a variable in a function, the static keyword specifies that the
variable retains its state between calls to that function.

•When we declare a data member in a class declaration, the static keyword


specifies that one copy of the member is shared by all instances of the class. A
static data member must be defined at file scope.

•When we declare a member function in a class declaration, the static keyword


specifies that the function is shared by all instances of the class. A static
member function cannot access an instance member because the function does
not have an implicit this pointer. To access an instance member, declare the
function with a parameter that is an instance pointer or reference.

•We cannot declare the members of a union as static. However, a globally


declared anonymous union must be explicitly declared static.

4. Does friend function violate encapsulation? Explain with an


example.
Answer:

No! If they're used properly, they enhance encapsulation.

You often need to split a class in half when the two halves will have different
numbers of instances or different lifetimes. In these cases, the two halves
usually need direct access to each other (the two halves used to be in the same
class, so you haven't increased the amount of code that needs direct access to a
data structure; you've simply reshuffled the code into two classes instead of
one). The safest way to implement this is to make the two halves friends of each
other.

If you use friends like just described, you'll keep private things private. People
who don't understand this often make naive efforts to avoid using friendship in
situations like the above, and often they actually destroy encapsulation. They
either use public data (grotesque!), or they make the data accessible between the
halves via public get() and set() member functions. Having a public get() and
set() member function for a private datum is OK only when the private datum
"makes sense" from outside the class (from a user's perspective). In many cases,
these get()/set() member functions are almost as bad as public data: they hide
(only) the name of the private datum, but they don't hide the existence of the
private datum.

Similarly, if you use friend functions as a syntactic variant of a class's public


access functions, they don't violate encapsulation any more than a member
function violates encapsulation. In other words, a class's friends don't violate the
encapsulation barrier: along with the class's member functions, they are the
encapsulation barrier.
(Many people think of a friend function as something outside the class. Instead,
try thinking of a friend function as part of the class's public interface. A friend
function in the class declaration doesn't violate encapsulation any more than a
public member function violates encapsulation: both have exactly the same
authority with respect to accessing the class's non-public parts.)

5. What are the some advantages or disadvantages of using friend


functions?
Answer:

Merits of friend function:


 Friend function acts as bridge between two classes by operating on their
private datas.
 Must have access to source code for the class to make a function into
friend.
 Able to access members without need of inheriting the class.
 Allows a more abvious syntax for calling a function rather than member
function.
For example num.square(); is less obvious than square(num);
 Can be declared either in the public or the private part of a class.
 Can be used to increase versatility of overloaded operator.

Demerits of friend function:


 Friend functions have access to private members of a class from outside
the class which violates the law of data hiding.
 Breach of data integrity
 Conceptually messy
 Lead to spaghetti-code situation if numerous friends muddy the boundary
between classes.
 Maximum size of memory will be occupied by objects according to size
of friend members.
 Cannot do any run time polymorphism in its members
6. “A friend function is a function that can access the private
members of a class as though it were a member of that class”.
Explain?
Answer:

Let us look at a sample program given below to access the private data of a
class by non-member functions through friend function. The program declares a
private class example representing variable x and function to input the value for
the same. The friend function to display the value of x takes an object as
argument with the help of which private variable x can be accessed.

#include <iostream.h>
#include <conio.h>
class example
{
private:
int x; .
public:
void getdata ()
{
cout << “Enter the value ofx”<< “\n”;
cin >> x;
}
friend void disp(example);
};
void disp(example eg)
{
cout << “Display the entered number”<< eg.x<< “\n”;
}
main ()
{
example egl;
eg1.getdata();
disp(eg1);
getche();
}

You should see the following output.

Enter the value of x


4
Display the entered number 4
There are also other areas of application for friend function. The friend function
can also be defined within the scope of a class definition itself. Friend function
may also have inline member functions. If the friend function is defined in the
class, then the inline code substitution is done automatically. But if defined
outside the class, then it is necessary to precede the return type with the
keyword inline to make the inline code substitution.

7. Write a program which is using the friend function in the


nested classes and local classes.
Answer: Friend Function in Nested Classes
Friend functions declared in a nested class are considered to be in the scope of
the nested class, not the enclosing class. Therefore, the friend functions gain no
special access privileges to members or member functions of the enclosing
class. If you want to use a name that is declared in a nested class in a friend
function and the friend function is defined in file scope, use qualified type
names as follows:

// friend_functions_and_nested_classes.cpp
#include <string.h>
char *rgszMessage[255];
class BufferedIO
{
public:
class BufferedInput
{
public:
friend int GetExtendedErrorStatus();
static char *message;
int iMsgNo;
};
};
char *BufferedIO::BufferedInput::message;
int GetExtendedErrorStatus()
{
int iMsgNo = 1; // assign arbitrary value as message number
strcpy( BufferedIO::BufferedInput::message,
rgszMessage[iMsgNo] );
return iMsgNo;
}
int main()
{
}

Friend Function in Local Classes


The name of a friend function or class first introduced in a friend declaration is
not in the scope of the class granting friendship (also called the enclosing class)
and is not a member of the class granting friendship.
The name of a function first introduced in a friend declaration is in the scope of
the first nonclass scope that contains the enclosing class. The body of a function
provided in a friend declaration is handled in the same way as a member
function defined within a class. Processing of the definition does not start until
the end of the outermost enclosing class. In addition, unqualified names in the
body of the function definition are searched for starting from the class
containing the function definition.
If the name of a friend class has been introduced before the friend declaration,
the compiler
searches for a class name that matches the name of the friend class beginning at
the scope of the friend declaration. If the declaration of a nested class is
followed by the declaration of a friend class with the same name, the nested
class is a friend of the enclosing class.

The scope of a friend class name is the first nonclass enclosing scope. For
example:
class A {
class B { // arbitrary nested class definitions
friend class C;
};
};
is equivalent to:
class C;
class A {
class B { // arbitrary nested class definitions
friend class C;
};
};
Unit 6: Constructors and Destructors

1. Write a program to calculate prime number using constructor.


Answer:

#include<iostream>
using namespace std;

class prime
{
int a,k,i;
public:
prime(int x)
{
a=x;
}
void calculate()
{
k=1;
{
for(i=2;i<=a/2;i++)

if(a%i==0)
{
k=0;
break;
}
else
{
k=1;
}
}
}

void show()
{
if(k==1)
cout<< "\nThe Number is prime Number.\n";
else
cout<<"\nThe Number is Not prime.\n";
}
};

int main()
{
int a;
cout<<"\nEnter any Number: ";
cin>>a;
prime obj(a);
obj.calculate();
obj.show();

return 0;
}

Output:
Enter any Number: 1231

The Number is prime Number.

Process returned 0

2. Is there any difference between List x; and List x ();? Explain.


Answer:

A big difference!

Suppose that List is the name of some class. Then function f() declares a local
List object called x:

void f()
{
List x; // Local object named x (of class List)
...
}
But function g() declares a function called x() that returns a List:
void g()
{
List x(); // Function named x (that returns a List)
...
}

3. Can one constructor of a class call another constructor of the


same class to initialize the this object? Justify your answers with
an example.
Answer:
Let's work an example. Suppose you want your constructor Foo::Foo(char) to
call another constructor of the same class, say Foo::Foo(char,int), in order
that Foo::Foo(char,int) would help initialize the this object. Unfortunately
there's no way to do this in C++.

Some people do it anyway. Unfortunately it doesn't do what they want. For


example, the line Foo(x, 0); does not call Foo::Foo(char,int) on the this
object. Instead it calls Foo::Foo(char,int) to initialize a temporary, local
object (not this), then it immediately destructs that temporary when control
flows over the ;.
class Foo {
public:
Foo(char x);
Foo(char x, int y);
...
};

Foo::Foo(char x)
{
...
Foo(x, 0); // this line does NOT help initialize the this
object!!
...
}
You can sometimes combine two constructors via a default parameter:
class Foo {
public:
Foo(char x, int y=0); // this line combines the two constructors
...
};
If that doesn't work, e.g., if there isn't an appropriate default parameter that
combines the two constructors, sometimes you can share their common code in
a private init() member function:
class Foo {
public:
Foo(char x);
Foo(char x, int y);
...
private:
void init(char x, int y);
};

Foo::Foo(char x)
{
init(x, int(x) + 7);
...
}

Foo::Foo(char x, int y)
{
init(x, y);
...
}

void Foo::init(char x, int y)


{
...
}

4. Should my constructors use “initialization lists” or


“assignment”? Discuss.

Answer: Initialization lists. In fact, constructors should initialize as a rule all


member objects in the initialization list. One exception is discussed further
down.

Consider the following constructor that initializes member object x_ using an


initialization list: Fred::Fred() : x_(whatever) { }. The most common benefit of
doing this is improved performance. For example, if the expression whatever is
the same type as member variable x_, the result of the whatever expression is
constructed directly inside x_ — the compiler does not make a separate copy of
the object. Even if the types are not the same, the compiler is usually able to do
a better job with initialization lists than with assignments.
The other (inefficient) way to build constructors is via assignment, such as:
Fred::Fred() { x_ = whatever; }. In this case the expression whatever causes a
separate, temporary object to be created, and this temporary object is passed
into the x_ object's assignment operator. Then that temporary object is
destructed at the ;. That's inefficient.

As if that wasn't bad enough, there's another source of inefficiency when using
assignment in a constructor: the member object will get fully constructed by its
default constructor, and this might, for example, allocate some default amount
of memory or open some default file. All this work could be for naught if the
whatever expression and/or assignment operator causes the object to close that
file and/or release that memory (e.g., if the default constructor didn't allocate a
large enough pool of memory or if it opened the wrong file).

Conclusion: All other things being equal, your code will run faster if you use
initialization lists rather than assignment.

Note: There is no performance difference if the type of x_ is some built-


in/intrinsic type, such as int or char* or float. But even in these cases, my
personal preference is to set those data members in the initialization list rather
than via assignment for consistency. Another symmetry argument in favor of
using initialization lists even for built-in/intrinsic types: non-static const and
non-static reference data members can't be assigned a value in the constructor,
so for symmetry it makes sense to initialize everything in the initialization list.

Now for the exceptions. Every rule has exceptions (hmmm; does "every rule has
exceptions" have exceptions? reminds me of Gödel's Incompleteness
Theorems), and there are a couple of exceptions to the "use initialization lists"
rule. Bottom line is to use common sense: if it's cheaper, better, faster, etc. to
not use them, then by all means, don't use them. This might happen when your
class has two constructors that need to initialize the this object's data members
in different orders. Or it might happen when two data members are self-
referential. Or when a data-member needs a reference to the this object, and you
want to avoid a compiler warning about using the this keyword prior to the {
that begins the constructor's body (when your particular compiler happens to
issue that particular warning). Or when you need to do an if/throw test on a
variable (parameter, global, etc.) prior to using that variable to initialize one of
your this members. This list is not exhaustive; please don't write me asking me
to add another "Or when...". The point is simply this: use common sense.
5. What is the “Named Constructor Idiom”?

Answer: A technique that provides more intuitive and/or safer construction


operations for users of your class.

The problem is that constructors always have the same name as the class.
Therefore the only way to differentiate between the various constructors of a
class is by the parameter list. But if there are lots of constructors, the differences
between them become somewhat subtle and error prone.

With the Named Constructor Idiom, you declare all the class's constructors in
the private or protected sections, and you provide public static methods
that return an object. These static methods are the so-called "Named
Constructors." In general there is one such static method for each different
way to construct an object.

For example, suppose we are building a Point class that represents a position on
the X-Y plane. Turns out there are two common ways to specify a 2-space
coordinate: rectangular coordinates (X+Y), polar coordinates (Radius+Angle).
(Don't worry if you can't remember these; the point isn't the particulars of
coordinate systems; the point is that there are several ways to create a Point
object.) Unfortunately the parameters for these two coordinate systems are the
same: two floats. This would create an ambiguity error in the overloaded
constructors:
class Point {
public:
Point(float x, float y); // Rectangular coordinates
Point(float r, float a); // Polar coordinates (radius and
angle)
// ERROR: Overload is Ambiguous: Point::Point(float,float)
};

int main()
{
Point p = Point(5.7, 1.2); // Ambiguous: Which coordinate
system?
...
}
One way to solve this ambiguity is to use the Named Constructor Idiom:
#include <cmath> // To get std::sin() and std::cos()

class Point {
public:
static Point rectangular(float x, float y); // Rectangular
coord's
static Point polar(float radius, float angle); // Polar
coordinates
// These static methods are the so-called "named constructors"
...
private:
Point(float x, float y); // Rectangular coordinates
float x_, y_;
};

inline Point::Point(float x, float y)


: x_(x), y_(y) { }

inline Point Point::rectangular (float x, float y)


{ return Point(x, y); }

inline Point Point::polar(float radius, float angle)


{ return Point(radius*std::cos(angle), radius*std::sin(angle)); }
Now the users of Point have a clear and unambiguous syntax for creating
Points in either coordinate system:
int main()
{
Point p1 = Point::rectangular (5.7, 1.2); // Obviously
rectangular
Point p2 = Point::polar(5.7, 1.2); // Obviously polar
...
}

6. What about returning a local variable by value? Does the local


exist as a separate object, or does it get optimized away?

Answer:
When your code returns a local variable by value, your compiler might optimize
away the local variable completely - zero space-cost and zero time-cost - the
local variable never actually exists as a distinct object from the caller's target
variable (see below for specifics about exactly what this means). Other
compilers do not optimize it away.

These are some (!) of the compilers that optimize away the local variable
completely:

 GNU C++ (g++) since at least version 3.3.3


 (Others need to be added; need more info)

These are some (!) of the compilers that do not optimize away the local
variable:

 Microsoft Visual C++.NET 2003


 (Others need to be added; need more info)

Here is an example showing what we mean in this FAQ:


class Foo {
public:
Foo(int a, int b);
void some_method();
...
};

void do_something_with(Foo& z);

Foo rbv()
{
Foo y = Foo(42, 73);
y.some_method ();
do_something_with(y);
return y;
}

void caller()
{
Foo x = rbv();
...
}
The question addressed in this FAQ is this: How many Foo objects actually get created in the
runtime system? Conceptually there could be as many as three distinct objects: the temporary
created by Foo(42, 73), variable y (in rbv()), and variable x (in caller()). However as we saw
earlier most compilers merge Foo(42, 73) and variable y into the same object, reducing the
total number of objects from 3 to 2. But this FAQ pushes it one step further: does y (in rbv())
show up as a distinct, runtime object from x (in caller())?

Some compilers, including but not limited to those listed above, completely
optimize away local variable y. In those compilers, there is only one Foo object
in the above code: caller()'s variable x is exactly identically the same object as
rbv()'s variable y.

They do this the same way as described earlier: the return-by-value in function
rbv() is implemented as pass-by-pointer, where the pointer points to the
location where the returned object is to be initialized.

So instead of constructing y as a local object, these compilers simply construct


*put_result_here, and everytime they see variable y used in the original source
code, they substitute *put_result_here instead. Then the line return y;
becomes simply return; since the returned object has already been constructed
in the location designated by the caller.
Here is the resulting (pseudo)code:
// Pseudo-code
void rbv(void* put_result_here) ← Original C++ code: Foo
rbv()
{
Foo_ctor((Foo*)put_result_here, 42, 73); ← Original C++ code: Foo
y = Foo(42,73);
Foo_some_method(*(Foo*)put_result_here); ← Original C++ code:
y.some_method();
do_something_with((Foo*)put_result_here); ← Original C++ code:
do_something_with(y);
return; ← Original C++ code:
return y;
}

void caller()
{
struct Foo x; ← Note: x is not initialized here!
rbv(&x); ← Original C++ code: Foo x = rbv();
...
}

Caveat: this optimization can be applied only when all a function's return
statements return the same local variable. If one return statement in rbv() returned
local variable y but another returned something else, such as a global or a
temporary, the compiler could not alias the local variable into the caller's
destination, x. Verifying that all the function's return statements return the same
local variable requires extra work on the part of the compiler writers, which is
usually why some compilers fail to implement that return-local-by-value
optimization.

7. Why are classes with static data members getting linker errors?

Answer:
Because static data members must be explicitly defined in exactly one
compilation unit. If you didn't do this, you'll probably get an "undefined
external" linker error. For example:

// Fred.h

class Fred {
public:
...
private:
static int j_; // Declares static data member Fred::j_
...
};
The linker will holler at you ("Fred::j_ is not defined") unless you define (as
opposed to merely declare) Fred::j_ in (exactly) one of your source files:

// Fred.cpp

#include "Fred.h"

int Fred::j_ = some_expression_evaluating_to_an_int;

// Alternatively, if you wish to use the implicit 0 value for static ints:
// int Fred::j_;

The usual place to define static data members of class Fred is file Fred.cpp (or
Fred.C or whatever source file extension you use).

8. How is a copy constructor different from a constructor?


Illustrate with suitable examples.
Answer:

Copy Constructor
A copy constructor method allows an object to be initialized with another object
of the same class. It implies that the values stored in data members of an
existing object can be copied into the data variables of the object being
constructed, provided the objects belong to the same class.
A copy constructor has a single parameter of reference type that refers to the
class itself as shown below:

abc::abc(abc & a)
{
x=a.x;
y=a.y;
}

Suppose we create an object myabc1 with two integer parameters as shown


below:
abc myabc1(1,2);
Having created myabc1, we can create another object of abc type, say myabc2
from myabc1, as shown below:
myabc2=abc(& myabc1);
The data values of myabc1 will be copied into the corresponding data variables
of object myabc2.
Another way of activating copy constructor is through assignment operator.
Copy constructors come into play when an object is assigned another object of
the same type, as shown below:
abc myabc1(1,2);
abc myabc2;
myabc2=myabc1;
Actually assignment operator (=) has been overloaded in C++ so that copy
constructor is invoked whenever an object is assigned another object of the
same type.

9. What is the purpose of having default arguments in a


constructor? Explain with suitable examples.
Answer:
Constructors with Default Arguments
This method is used to initialize object with user defined parameters at the time
of creation.
Consider the following Program that calculates simple interest. It declares a
class interest representing principal, rate and year. The constructor function
initializes the objects with principal and number of years. If rate of interest is
not passed as an argument to it the Simple Interest is calculated taking the
default value of rate of interest

#include <iostream.h>
#include <conio.h>
class interest
{ int principal, rate, year;
float amount;
public
interest (int p, int n, int r = 10);
void cal (void);
};
interest::interest (int p, int n, int r = 10)
{ principal = p; year = n; rate = r;
};
void interest::cal (void)
{
cout<< “Principal” <<principal;
cout << “\ Rate” <<rate;
cout<< “\ Year” <<year;
amount = (float) (p*n*r)/100;
cout<< “\Amount” <<amount;
};
main ( )
{
interest i1(1000,2);
interest i2(1000, 2,15);
clrscr( );
il.cal();
i2.cal();
}
interest i1(1000,2);
interest i2(1000,2, 15);
The data members principal and year of object i1 are initialized to 1000 and 2
respectively at the time when object i1 is created. The data member rate takes
the default value 10 whereas when the object 12 is created, principal, year and
rate are initialized to 1000,2 and 15 respectively. It is necessary to distinguish
between the default
constructor::construct();
and default argument constructor
construct::construct(int = 0)
The default argument constructor can be called with one or no arguments. When
it is invoked
with no arguments it becomes a default constructor. But when both these forms
are used in a
class, it causes ambiguity for a declaration like construct C1;
The ambiguity is whether to invoke construct: : construct ( ) or construct: :
construct (int=O)
Unit 7: Operator Overloading

1. Which operators are not allowed to be overloaded?

Answer:

Operators that cannot be Overloaded

Operator Purpose

. Class member access operator

.* Class member access operator

:: Scope Resolution Operator

?: Conditional Operator

Sizeof Size in bytes operator

# Preprocessor Directive

= Assignment operator

0 Function call operator

0 Subscripting operator

-> Class member access operator

2. What are the differences between overloading a unary operator


and that of a binary operator? Illustrate with suitable examples.
Answer:

Overloading Unary Operators


In case of unary operator overloaded using a member function no argument is
passed to the function whereas in case of a friend function a single argument
must be passed.
Following program overloads the unary operator to negate an object. The
operator function defined outside the class negates the individual data members
of the class integer.

#include <iostream.h>
#include <conio.h>
class integer
{
int x,y,z;
public:
void getdata(int a, int b, int c);
void disp(void);
void operator- (); // overload unary operator minus
};
void integer::getdata(int a, int b, int c)
{
x=a; y=b; z=c;
}
void integer::disp(void)
{
cout << x << “ “;
cout<< y<<“ “;
cout<< z<< “\n”;
}
void integer::operator- () // Defining operator- ()
{
x = -x; y = -y; z = -z;
}
void main ()
{
integer S;
S.getdata(11,-21,-31);
Cout<< “S: “;
S.disp();
-S;
cout<<“-S : “;
S.disp();
getch();
}
You should see the following output.
S: 11 -21 -31
-S:-11 21 31

Overloading Binary Operators


Binary Operators are operators, which require two operands to perform the
operation. When they are overloaded by means of member function, the
function takes one argument, whereas it takes two arguments in case of friend
function. This will be better understood by means of the following program.
The following program creates two objects of class integer and overloads the +
operator to add two object values.

#include <iostream.h>
#include <conio.h>
class integer
{
private:
int val;
public:
integer();
integer(int one );
integer operator+ (integer objb);
void disp();
};
integer::integer()
{
val = 0;
}
integer::integer(int one)
{
val = one;
}
integer integer::operator+ (integer objb)
{
integer objsum;
objsum.val = val + objb.val;
return (objsum);
}
void integer::disp()
{
cout<< “value =”<< val<< endl;
}
void main()
{
integer obj1(11);
integer obj2(22);
integer objsum;
objsum = objl + obj2;
obj1.disp ();
obj2.disp ();
objsum.disp();
getch();
}
You should see the following output.
value = 11
value = 22
value = 3

3. How many arguments are required in the definition of an


overloaded unary operator?
Answer: Unary operators, overloaded by means of a member function, take no
explicit argument and return no explicit values. But, those overloaded by means
of a friend function take one reference argument (the object of the relevant
class).

Operator to Overload Arguments passed to Argument passed to the


the Friend
Member Function Function
Unary Operator No 1

4. Write a note on unary operators?


Answer: A unary operator, in C#, is an operator that takes a single operand in
an expression or a statement. The unary operators in C# are +, -,!, ~, ++, -- and
the cast operator.

The signature of the declaration of a unary operator includes the operator token
and the type of parameter; it does not require the return type and the name of the
parameter.

All the C# unary operators have predefined implementation that will be used by
default in an expression. These unary operators can be overloaded in user-
defined types with custom implementation by defining static member functions
using the "operator" keyword.

The list of unary operators with their details includes:

 Unary Plus Operator (+): The result of an operation on a numeric type is


the value of the operand itself. This operator has been predefined for all
numeric types.
 Unary Minus Operator (-): This operator can be used to negate numbers
of the integer, floating-point and decimal type.
 Logical Complement (negation) Operator (!): This operator can be used
only with operands of Boole type.
 Bitwise Complement (negation) Operator (~): This operator can be used
with integer, unit, long and along operand types. The result of the
operation is a bitwise complement (inverse of the binary representation)
of the operand.
 Prefix Increment (++) and Decrement (--) Operator: The operand can be a
variable, property access, or an indexer access. With an increment
operator, the result of the operation for operands of integer type would be
the value incremented by 1. With a decrement operator, the result would
be the value decremented by 1 from the operand. The
increment/decrement operator can also be used with postfix notation
 Cast Operator: Used to build cast expressions for conversion to a given
type. This operator is represented by the symbol, "T," where T is the type
to which the operand or the result of the expression must be converted

5. What are the various rules for overloading operators?


Answer: Rules for Overloading Operators

To overload any operator, we need to understand the rules applicable Let us


revise some of
them which have already been explored.

1. Operators already predefined in the C++ compiler can be only overloaded.


Operator cannot change operator templates that is for example the increment
operator ++ is used only as unary operator. It cannot be used as binary operator.
2. Overloading an operator does not change its basic meaning. For example
assume the + operator can be overloaded to subtract two objects. But the code
becomes unreachable.

class integer
{
intx, y;
public:
int operator + ();
}
int integer: : operator + ( )
{
return (x-y);
}
3. Unary operators, overloaded by means of a member function, take no explicit
argument and return no explicit values. But, those overloaded by means of a
friend function take one reference argument (the object of the relevant class).
4. Binary operators overloaded through a member function take one explicit
argument and those which are overloaded through a friend function take two
explicit arguments.
5. Overloaded operators must either be a non-static class member function or a
global function.
A global function that needs access to private or protected class members must
be declared as a friend of that class. A global function must take at least one
argument that is of class or enumerated type or that is a reference to a class or
enumerated type.
Unit 8: Type Conversion
1. “In a mixed expression constants and variables are of different
data types.” Justify this statement with an example.
Answer: Type Conversions

In a mixed expression constants and variables are of different data types. The
assignment operations cause automatic type conversion between the operand as
per certain rules. The type of data to the right of an assignment operator is
automatically converted to the data type of variable on the left.

Consider the following example:


int x;
float y = 20.123;
x=y;

This converts float variable y to an integer before its value assigned to x. The
type conversion is automatic as far as data types involved are built in types. We
can also use the assignment operator in case of objects to copy values of all data
members of right hand object to the object on left hand. The objects in this case
are of same data type.

2. The constructor functions do not support conversion from a


class to basic type. Explain with a example.
Answer: Class Type to Basic Type

The constructor functions do not support conversion from a class to basic type.
C++ allows us to define a overloaded casting operator that convert a class type
data to basic type. The general form of an overloaded casting operator function,
also referred to as a conversion function, is:

operator typename ()
{
//Program statement
}
This function converts a class type data to type name. For example, the operator
double () converts a class object to type double, in the following conversion
function:
vector:: operator double()
{
double sum = 0;
for(int I = 0; i<size; i++)
sum = sum + v[i] * v[i ]; //scalar magnitude
return sqrt(sum);
}

3. Explicit type conversions between objects of different types


lead, at best, to code that is difficult to read. Discuss.
Answer: It is the process of converting one type into another. In other words
converting an expression of a given type into another is called type casting.
A type conversion may either be explicit or implicit, depending on whether it is
ordered by the programmer or by the compiler. Explicit type conversions (casts)
are used when a programmer want to get around the compiler’s typing system;
for success in this endeavour, the programmer must use them correctly.
Problems which the compiler avoids may arise, such as if the processor
demands that data of a given type be located at certain addresses or if data is
truncated because a data type does not have the same size as the original type on
a given platform. Explicit type conversions between objects of different types
lead, at best, to code that is difficult to read.

4. The assignment operations cause automatic type conversion


between the operand as per certain rules. Describe.
Answer:

In a mixed expression constants and variables are of different data types. The
assignment operations cause automatic type conversion between the operand as
per certain rules.
The type of data to the right of an assignment operator is automatically
converted to the data type of variable on the left.
Consider the following example:
int x;
float y = 20.123;
x=y;

This converts float variable y to an integer before its value assigned to x. The
type conversion is automatic as far as data types involved are built in types. We
can also use the assignment operator in case of objects to copy values of all data
members of right hand object to the object on left hand. The objects in this case
are of same data type.

5. Implicit conversions also include constructor or operator


conversions, which affect classes that include specific constructors
or operator functions to perform conversions. Explain with and
example?
Answer: Implicit conversion
Implicit conversions do not require any operator. They are automatically
performed when a value is copied to a compatible type. For example:

1 short a=2000;
2 int b;
3 b=a;

Here, the value of a has been promoted from short to int and we have not had to
specify any type-casting operator. This is known as a standard conversion.
Standard conversions affect fundamental data types, and allow conversions such
as the conversions between numerical types (short to int, int to float, double to
int...), to or from bool, and some pointer conversions. Some of these
conversions may imply a loss of precision, which the compiler can signal with a
warning. This warning can be avoided with an explicit conversion.

Implicit conversions also include constructor or operator conversions, which


affect classes that include specific constructors or operator functions to perform
conversions. For example:

1 class A {};
2 class B { public: B (A a) {} };
3
4 A a;
5 B b=a;

Here, an implicit conversion happened between objects of class A and class B,


because B has a constructor that takes an object of class A as parameter.
Therefore implicit conversions from A to B are allowed.

6. There are three types of situations that arise where data


conversion are between incompatible types. What are three
situations explain briefly.
Answer: There are three types of situations that arise where data conversion
are between incompatible types.
1. Conversion from built in type to class type.
2. Conversion from class type to built in type.
3. Conversion from one class type to another.

Basic Type to Class Type


A constructor was used to build a matrix object from an int type array.
Similarly, we used another constructor to build a string type object from a char*
type variable. In these examples constructors performed a defect type
conversion from the argument’s type to the constructor’s class type.

Consider the following constructor:


string::string(char*a)
{
length = strlen(a);
name=new char[len+1];
strcpy(name,a);
}
This constructor builds a string type object from a char* type variable a. The
variables length and name are data members of the class string. Once you define
the constructor in the class string, it can be used for conversion from char* type
to string type.
Example:
string s1, s2;
char* name1 = “Good Morning”;
char* name2 = “STUDENTS”;
s1 = string(name1);
s2 = name2;

The program statement


s1 = string (name1);
first converts name1 from char* type to string type and then assigns the string
type values to the object s1. The statement
s2 = name2;
performs the same job by invoking the constructor implicitly.

Consider the following example


class time
{
int hours;
int minutes;
public:
time (int t) II constructor
{
hours = t / 60; //t is inputted in minutes
minutes = t % 60; .
}
};

In the following conversion statements:


time T1; //object T1 created
int period = 160;
T1 = period; //int to class type
The object T1 is created. The variable period of data type integer is converted
into class type time by invoking the constructor. After this conversion, the data
member hours of T1 will have value 2 arid minutes will have a value of 40
denoting 2 hours and 40 minutes.

Class Type to Basic Type


The constructor functions do not support conversion from a class to basic type.
C++ allows us to define a overloaded casting operator that convert a class type
data to basic type. The general form of an overloaded casting operator function,
also referred to as a conversion function, is:
operator typename ()
{
//Program statement
}

This function converts a class type data to type name. For example, the operator
double() converts a class object to type double, in the following conversion
function:
vector:: operator double()
{
double sum = 0;
for (int I = 0; i<size; i++)
sum = sum + v[i] * v[i ]; //scalar magnitude
return sqrt(sum);
}

The casting operator should satisfy the following conditions.


1. It must be a class member.
2. It must not specify a return type.
3. It must not have any arguments. Since it is a member function, it is invoked
by the object and therefore, the values used for, Conversion inside the function
belongs to the object that invoked the function. As a result function does not
need an argument.
In the string example discussed earlier, we can convert the object string to char*
as follows:
string::operator char*()
{
retum(str);
}

Class Type to another Class Type


We have just seen data conversion techniques from a basic to class type and a
class to basic type. But sometimes we would like to convert one class data type
to another class type.

Example:
Objl = Obj2 ; //Obj1 and Obj2 are objects of different classes.
Obj1 is an object of class one and Obj2 is an object of class two. The class two
type data is converted to class one type data and the converted value is assigned
to the Obj1. Since the conversion takes place from class two to class one, two is
known as the source and one is known as the destination class.
Such conversion between objects of different classes can be carried out by
either a constructor or a conversion function. Which form to use, depends upon
where we want the type-conversion function to be located, whether in the
source class or in the destination class.
We studied that the casting operator function Operator typename()
Converts the class object of which it is a member to typename. The type name
may be a built-in type or a user defined one (another class type). In the case of
conversions between objects, typename refers to the destination class.
Therefore, when a class needs to be converted, a casting operator function can
be used. The conversion takes place in the source class and the result is given to
the destination class object.
Let us consider a single-argument constructor function which serves as an
instruction for converting the argument’s type to the class type of which it is a
member. The argument belongs to the source class and is passed to the
destination class for conversion. Therefore the conversion constructor must be
placed in the destination class.

7. Write a program which the conversion of class type to basic


type conversion.
Answer:

/* Program to demonstrate Class type to Basic type conversion. */

#include "iostream.h"
#include "conio.h"
#include "iomanip.h"

class Time
{
int hrs,min;
public:
Time (int ,int); // constructor
operator int(); // casting operator function
~Time() // destructor
{
cout<<"Destructor called..."<<endl;
}
};

Time::Time (int a,int b)


{
cout<<"Constructor called with two parameters..."<<endl;
hrs=a;
min=b;
}

Time:: operator int()


{
cout<<"Class Type to Basic Type Conversion..."<<endl;
return (hrs*60+min);
}

void main()
{
clrscr();
int h,m,duration;
cout<<"Enter Hours ";
cin>>h;
cout<<"Enter Minutes ";
cin>>m;
Time t(h,m); // construct object
duration = t; // casting conversion OR duration = (int)t
cout<<"Total Minutes are "<<duration;
cout<<"2nd method operator overloading "<<endl;
duration = t.operator int();
cout<<"Total Minutes are "<<duration;

getch();
}
Unit 9: Inheritance
1. Consider a situation where three kinds of inheritance are
involved. Explain this situation with an example.
Answer: Hybrid Inheritance

There could be situations where we need to apply two or more types of


inheritance to design a program. Basically Hybrid Inheritance is the
combination of one or more types of the inheritance.
Here is one implementation of hybrid inheritance.

//Program to show the simple hybrid inheritance


# include < isostream.h>
# include < conio.h>
class student //base class declaration
{
protected:
int r_no;
public:
void get _n (int a) {
r_no - a; }
void put_n (void)
{
cout << “Roll No.: “<< r_no;
cout << “In”;
}
};
class test : public student
{ //Intermediate base class
protected: int part1, par 2; //(base for result)
public :
void get_m (int x, int y) {
part1 = x; part 2 = y; }
void put_m (void) {
cout << “marks obtained: “<< “In”
<< “Part 1 = “<< part1 << “In”
<< “Part 2 = “<< part2 << “In”;
}
};
class sports // base for result
{
protected: int score;
public:
void get_s (int s) {
score = S1 }
void put_s (void) {
cout << “sports wt. : “<< score << “\n\n”;
}
};
class result : public test, public sports//Derived from test & sports
{
int total;
public:
void display (void);};
void result : : display (void)
{
total = part1 + part2 + score;
put_n ( );
put_m ( );
put_s ( );
cout << “Total score: “<<total<< “\n”;
}
main ( )
{
clrscr ( );
result S1;
S1.get_n (347);
S1.get_m (30, 35);
S1.get_s (7);
S1.dciplay ( );
}

2. What is the difference between protected and private


members?
Answer: The members of base class which are inherited by the derived class
and their accessibility is determined by visibility modes. Visibility modes are:

1. Private: When a base class is privately inherited by a derived class, ‘public


members’ of
the base class become private members of the derived class and therefore the
public members of the base class can be accessed by its own objects using the
dot operator. The result is that we have no member of base class that is
accessible to the objects of the derived class.

2. Public: On the other hand, when the base class is publicly inherited, ‘public
members’ of the base class become ‘public members’ of derived class and
therefore they are accessible to the objects of the derived class.

3. Protected: C++ provides a third visibility modifier, protected, which serve a


little purpose in the inheritance. A member declared as protected is accessible
by the member functions within its class and any class immediately derived
from it. It cannot be accessed by functions outside these two classes.

3. Differentiate between public and private inheritances with


suitable examples.

Answer: In C++, the most common type of inheritance is public.


The public type of inheritance is used in order to broaden the parent class with
some functionalities or some data members.

This type of public inheritance is sometimes called the ” is “, as the parent class
and the child class are of the same type and that could be seen with conversions,
where the child class has more to it, than parent one.

The private inheritance is of different type, it is of ” has” type.

This means that private inheritance is suitable for situations in which we need to
prevent main program to accidentally access some of the methods inherited
from the parent class.

The protected inheritance is less restrictive than private and it is useful when we
need some of the implementations from grandparent class.

The following table will illustrate this difference:

Public Protected Private


Members Members Members
Public Inheritance public protected private
Protected
protected protected private
inheritance
Private inheritance private private private

.
As we can see from the above table, private inheritance is the most restrictive
and the protected is somehow in between the private and the public type.

Private Inheritance Example Program

In order to understand how to use private inheritance, let us look at the


following example program that uses two classes: the parent and the child
classes.

# cat p1.cpp
#include <iostream>

using namespace std;

class Parent{
public:
void parentMethod ( void ){ cout<<"Inside parent method"<<endl;}
};

class Child: private Parent{


public:
void childMethod (void){
cout<<"Inside child method"<<endl;
parentMethod ();
}
};

int main( void ){


Child C;
C.childMethod();
return 0;
}

In the above example code:

 We created one object of the Child type with name “C”


 Then we applied childMethod(), which has some message and it will in-
turn call the method parentMethod() that is placed in its body.
 If you try to call method parentMethod() on the object “C”, you will get
error message. From this we observe the most important property of
private inheritance that it will disable the child object to accidental access
some of the grand parent methods that would get inherited with public
inheritance.

The following is the output of the above program:

# g++ p1.cpp

# ./a.out
Inside child method
Inside parent method

Protected Inheritance Example Code

The following example explains how the protected inheritance could be used in
the program.

# cat p2.cpp
#include <iostream>

using namespace std;

class GrandParent{
public:
void grandParentMethod ( void ){ cout<<"Method in the grand parent
class"<<endl; }
};

class Parent : protected GrandParent{


public:
void parentMethod( void ){ cout<<"Method in the parent class"<<endl; }
};

class Child: protected Parent{


public:
void
childMethod ( void ){
cout<<"Method in the child class"<<endl;
parentMethod();
grandParentMethod();
}
};

int
main( void ){

Child C;
C.childMethod();
return 0;

In the above example code:

 We created three levels of inheritance with classes: the grand parent, the
parent and child.
 From this chain we have one method at the each of the classes.
 The main function has one object of the Child type, afterwards we call the
method childMethod (), which has two calls of parentMethod () and
grandParentMethod ().

The following is the output of the above program:

# g++ p2.cpp

# ./a.out
Method in the child class
Method in the parent class
Method in the grand parent class

From these two examples, we have learned how this type of inheritance is
implemented.

Now, I need to say that in this case, we have used protected inheritance in the
parent class and if we have used the private inheritance in the second layer of
chain inheritance, we would’ve end up with an error message.

In order to make the most of this two types of inheritance, I will show you how
you could use particular method from parent class if we overload it with some
name method in the child class.
That task should be achieved in the following three ways:

 Parent::parentMethod();
 using Parent::Method();
 Object.Parent::parentMethod ().

In another words, if the child class hides some of the methods from the parent
class, we will have already mentioned methodologies to access hidden methods.

4. Explain how a sub-class may inherit from multiple classes.


Answer: Multiple Inheritance
A class can inherit the attributes of two or more classes. This mechanism is
known as ‘MULTIPLE INHERITANCE’.

Where the visibility refers to the access specifiers i.e. public, private or
protected. Following program shows the multiple inheritance.
# include < iostream.h>
# include < conio.h>
class father //Declaration of base class1
{
int age;
char name [20];
public:
void get ( );
void show ( );
};
void father: : get ( )
{
cout << “your father name please”;
cin >> name;
cout << “Enter the age”; Notes
cin >> age;
}
void father : : show ( )
{
cout<< “In my father’s name is:”<<name<< “In my father’s age
is: <<age;
}
class mother //Declaration of base class 2
{
char name [20];
int age;
public:
void get ( )
{
cout << “mother’s name please” << “In”;
cin >> name;
cout << “mother’s age please” << “in”;
cin >> age;
}
void show ( )
{
cout << “In my mother’s name is: “<<name;
cout << “In my mother’s age is: “<<age;
class daughter : public father, public mother //derived class:
inheriting
{ //publicly
char name [20]; //the features of both the base class
int std;
public:
void get ( );
void show ( );
};
void daughter :: get ( )
{
father:: get ( );
mother:: get ( );
cout << “child’s name: “;
cin >> name;
cout << “child’s standard”;
cin >> std;
}
void daughter:: show ( )
{
father:: show ( );
nfather :: show ( );
cout << “In child’s name is : “<<name;
cout << “In child’s standard: “<<std;
}
main ( )
{
clrscr ( );
daughter d1;
d1.get ( );
d1.show ( );
}

5. What is the purpose of virtual base classes?


Answer: Virtual Base Classes
We have just discussed a situation which would require the use of both multiple
and multi level inheritance. Consider a situation, where all the three kinds of
inheritance, namely multi-level, multiple and hierarchical are involved. Let us
say the ‘child’ has two direct base classes ‘parent1’ and ‘parent2’ which
themselves has a common base class ‘grandparent’. The child inherits the traits
of ‘grandparent’ via two separate paths. It can also be inherit directly as shown
by the broken line. The grandparent is sometimes referred to as ‘INDIRECT
BASE CLASS’. Now, the inheritance by the child might cause some problems.
All the public and protected members of ‘grandparent’ are inherited into ‘child’
twice, first via ‘parent1’ and again via ‘parent2’. So, there occurs a duplicacy
which should be avoided.
The duplication of the inherited members can be avoided by making common
base class as the virtual base class: for e.g.

class g_parent
{
//Body
};
class parent1: virtual public g_parent
{
// Body
};
class parent2: public virtual g_parent
{
// Body
};
class child : public parent1, public parent2
{
// body
};
When a class is virtual base class, C++ takes necessary care to see that only one
copy of that class is inherited, regardless of how many inheritance paths exists
between virtual base class and derived class.

//Program to show the virtual base class


# include < iostream.h>
# include < conio.h>
class student // Base class declaration
{
protected:
int r_no;
public:
void get_n (int a)
{ r_no = a;}
void put_n (void)
{ cout << “Roll No.: “<< r_no<<“In”;}
};
class test : virtual public student //Virtually
declared common
{ //base class 1
protected:
int para1;
int para2;
public:
void get_m (int x, int y)
{ part1= x; part2=y;}
void put.m (void)
{
cout <<“marks obtained: “<< “In”;
cout << “part1 = “ << part1 <<“In”;
cout << “part2 = “<< part2 << “In”;
}
};

class sports: public virtual student //virtually


declared common
{ //base class 2
protected:
int score;
public:
void get_s (int a) {
score = a;
}
void put_s (void)
{ cout << “sports wt.: “<<score<< “\n”;}
};
class result: public test, public sports //derived class
{
private : int total;
public:
void show (void);
};
void result : : show (void)
{ total = part1 + part2 + score;
put_n ( );
put_m ( );
put_s ( ); cout <<“\n total score= “<<total<<“\n”;
}
main ( )
{
clrscr ( );
result S1;
S1.get_n (345)
S1.get_m (30, 35);
S1.get-S (7);
S1.show ( );
}
Unit 10: Virtual Functions and
Polymorphism
1. Make the distinction between virtual functions and virtual base
class?

Answer: Virtual Functions

A virtual function is a member function that you expect to be redefined in


derived classes. When you refer to a derived class object using a pointer or a
reference to the base class, you can call a virtual function for that object and
execute the derived class's version of the function.

Virtual functions ensure that the correct function is called for an object,
regardless of the expression used to make the function call.

Suppose a base class contains a function declared as virtual and a derived class
defines the same function. The function from the derived class is invoked for
objects of the derived class, even if it is called using a pointer or reference to the
base class. The following example shows a base class that provides an
implementation of the PrintBalance function and two derived classes

Virtual base class


- An ambiguity can arise when several paths exist to a class from the same base
class. This means that a child class could have duplicate sets of members
inherited from a single base class.
- C++ solves this issue by introducing a virtual base class. When a class is made
virtual, necessary care is taken so that the duplication is avoided regardless of
the number of paths that exist to the child class.
- When two or more objects are derived from a common base class, we can
prevent multiple copies of the base class being present in an object derived from
those objects by declaring the base class as virtual when it is being inherited.
Such a base class is known as virtual base class. This can be achieved by
preceding the base class’ name with the word virtual.
2. What is the difference between virtual and non-virtual member
functions?

Answer: Non-virtual member functions are resolved statically. That is, the
member function is selected statically (at compile-time) based on the type of the
pointer (or reference) to the object.

In contrast, virtual member functions are resolved dynamically (at run-time).


That is, the member function is selected dynamically (at run-time) based on the
type of the object, not the type of the pointer/reference to that object. This is
called "dynamic binding." Most compilers use some variant of the following
technique: if the object has one or more virtual functions, the compiler puts a
hidden pointer in the object called a "virtual-pointer" or "v-pointer." This v-
pointer points to a global table called the "virtual-table" or "v-table."

The compiler creates a v-table for each class that has at least one virtual
function. For example, if class Circle has virtual functions for draw() and
move() and resize(), there would be exactly one v-table associated with class
Circle, even if there were a gazillion Circle objects, and the v-pointer of each of
those Circle objects would point to the Circle v-table. The v-table itself has
pointers to each of the virtual functions in the class. For example, the Circle v-
table would have three pointers: a pointer to Circle::draw (), a pointer to
Circle::move (), and a pointer to Circle::resize ().

During a dispatch of a virtual function, the run-time system follows the object's
v-pointer to the class's v-table, then follows the appropriate slot in the v-table to
the method code.

The space-cost overhead of the above technique is nominal: an extra pointer per
object (but only for objects that will need to do dynamic binding), plus an extra
pointer per method (but only for virtual methods). The time-cost overhead is
also fairly nominal: compared to a normal function call, a virtual function call
requires two extra fetches (one to get the value of the v-pointer, a second to get
the address of the method). None of this runtime activity happens with non-
virtual functions, since the compiler resolves non-virtual functions exclusively
at compile-time based on the type of the pointer.
3. What happens in the hardware when we call a virtual
function? How many layers of indirection are there? How much
overhead isthere?

Answer: Let's work an example. Suppose class Base has 5 virtual functions:
virt0 () through virt4 ().

// Your original C++ source code

class Base {
public:
virtual arbitrary_return_type virt0(...arbitrary params...);
virtual arbitrary_return_type virt1(...arbitrary params...);
virtual arbitrary_return_type virt2(...arbitrary params...);
virtual arbitrary_return_type virt3(...arbitrary params...);
virtual arbitrary_return_type virt4(...arbitrary params...);
...
};
Step #1: the compiler builds a static table containing 5 function-pointers,
burying that table into static memory somewhere. Many (not all) compilers
define this table while compiling the .cpp that defines Base's first non-inline
virtual function. We call that table the v-table; let's pretend its technical name is
Base:: vtable. If a function pointer fits into one machine word on the target
hardware platform, Base:: vtable will end up consuming 5 hidden words of
memory. Not 5 per instance, not 5 per function; just 5. It might look something
like the following pseudo-code:

// Pseudo-code (not C++, not C) for a static table defined within file Base.cpp

// Pretend FunctionPtr is a generic pointer to a generic member function


// (Remember: this is pseudo-code, not C++ code)
FunctionPtr Base:: vtable[5] = {
&Base::virt0, &Base::virt1, &Base::virt2, &Base::virt3, &Base::virt4
};
Step #2: the compiler adds a hidden pointer (typically also a machine-word) to
each object of class Base. This is called the v-pointer. Think of this hidden
pointer as a hidden data member, as if the compiler rewrites your class to
something like this:

// Your original C++ source code


class Base {
public:
...
FunctionPtr* vptr; ← supplied by the compiler, hidden from the
programmer
...
};
Step #3: the compiler initializes this-> vptr within each constructor. The idea
is to cause each object's v-pointer to point at its class's v-table, as if it adds the
following instruction in each constructor's init-list:

Base::Base(...arbitrary params...)
: vptr(&Base:: vtable[0]) ← supplied by the compiler, hidden from the
programmer
...
{
...
}
Now let's work out a derived class. Suppose your C++ code defines class Der
that inherits from class Base. The compiler repeats steps #1 and #3 (but not #2).
In step #1, the compiler creates a hidden v-table, keeping the same function-
pointers as in Base:: vtable but replacing those slots that correspond to
overrides. For instance, if Der overrides virt0() through virt2() and inherits the
others as-is, Der's v-table might look something like this (pretend Der doesn't
add any new virtuals):

// Pseudo-code (not C++, not C) for a static table defined within file Der.cpp

// Pretend FunctionPtr is a generic pointer to a generic member function


// (Remember: this is pseudo-code, not C++ code)
FunctionPtr Der:: vtable[5] = {
&Der::virt0, &Der::virt1, &Der::virt2, &Base::virt3, &Base::virt4
}; ^^^^----------^^^^---inherited as-is
In step #3, the compiler adds a similar pointer-assignment at the beginning of
each of Der's constructors. The idea is to change each Der object's v-pointer so
it points at its class's v-table. (This is not a second v-pointer; it's the same v-
pointer that was defined in the base class, Base; remember, the compiler does
not repeat step #2 in class Der.)

Finally, let's see how the compiler implements a call to a virtual function. Your
code might look like this:
// Your original C++ code

void mycode(Base* p)
{
p- >virt3();
}
The compiler has no idea whether this is going to call Base::virt3() or
Der::virt3() or perhaps the virt3() method of another derived class that doesn't
even exist yet. It only knows for sure that you are calling virt3 () which happens
to be the function in slot #3 of the v-table. It rewrites that call into something
like this:

// Pseudo-code that the compiler generates from your C++

void mycode(Base* p)
{
p-> vptr[3](p);
}
On typical hardware, the machine-code is two 'load's plus a call:

1. The first load gets the v-pointer, storing it into a register, say r1.
2. The second load gets the word at r1 + 3*4 (pretend function-pointers are
4-bytes long, so r1+12 is the pointer to the right class's virt3() function).
Pretend it puts that word into register r2 (or r1 for that matter).
3. The third instruction calls the code at location r2.

4. Write a program which uses a polymorphism with pointers.


Answer:
#include <iostream>
using namespace std;

class Polygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
};

class Rectangle: public Polygon {


public:
int area()
{ return width*height; }
};

class Triangle: public Polygon {


public:
int area()
{ return width*height/2; }
};

int main () {
Rectangle rect;
Triangle trgl;
Polygon * ppoly1 = &rect;
Polygon * ppoly2 = &trgl;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
cout << rect.area() << '\n';
cout << trgl.area() << '\n';
return 0;
}

5. Write a program to use constructors and destructors in


inheritance.
Answer:
#include <iostream>

using namespace std;

class Line {
public:
void setLength ( double len );
double getLength( void );
Line(); // This is the constructor
private:
double length;
};

// Member functions definitions including constructor


Line::Line(void) {
cout << "Object is being created" << endl;
}
void Line::setLength( double len ) {
length = len;
}
double Line::getLength( void ) {
return length;
}

// Main function for the program


int main() {
Line line;

// set line length


line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;

return 0;
}

When the above code is compiled and executed, it produces the following result

Object is being created
Length of line: 6

6. What is the purpose of a pure virtual function? Illustrate with a


suitable example.
Answer: In many situations, when complete definition of a function is not
defined in the base class or there is a condition that derived class must override
the particular function. In such case we need to declare a function as pure
virtual function.

A pure virtual function has no definition in the base class. Syntax for declaring
a pure virtual function is as follows:
virtualret_typefun_name(parameter_list)=0;

If the derived class is not providing the definition of pure virtual function then a
compile time error will be generated.

A class that contains one or more than one pure virtual function is called as
abstract class. We cannot create the object of abstract class.

Example:
#include< iostream>
using namespace std;
classbaseClass
{
public:
virtual void show()=0;
};
classderiveClass: public baseClass
{
public:
void show()
{
cout << "Welcome";
}
};
int main() {

deriveClassobj;
obj.show();

return 0;
}
Unit 11: Pointers and Dynamic Memory
Management
1. How does pointer variable differ from simple variable?
Answer:
Normal variables carry the specified data where as the
pointer variable carried the address of the specified data,,,,,
eg: if we give int x =10; ptr p=*x;here x is the normal
variable carries 10 and pointer variable is p which carried
address of the integer variable x.

OR

Normal variable stores a value of the given datatype where


as the pointer variable stores the address of a variable.
for example
int n=10;
int *p;
p=&n;
here p is a pointer variable and n is a normal
variable.p stores the address of n where as n stores an
integer value.
*p prints the value of n,p prints the address
of n.

OR

Normal variable is a variable which can hold a value as like


eg. int,float or char,it may be signed or unsigned and take
different memory space as per as their data type. But the
pointer variable is a variable which hold the address of a
another variable,and it is obviously unsigned and take
always 2 byte in memory space.
2. How do we create and use an array of pointer-to-member-
function?

Answer: Use both the typedef and the #define macro described earlier, and
you're 90% done.

Step 1: create a typedef:

class Fred {
public:
int f(char x, float y);
int g(char x, float y);
int h(char x, float y);
int i(char x, float y);
...
};

// FredMemFn points to a member of Fred that takes (char,float)


typedef int (Fred::*FredMemFn)(char x, float y);
Step 2: create a #define macro:

#define CALL_MEMBER_FN(object,ptrToMember)
((object).*(ptrToMember))
Now your array of pointers-to-member-functions is straightforward:

FredMemFn a[] = { &Fred::f, &Fred::g, &Fred::h, &Fred::i };


And your usage of one of the member function pointers is also straightforward:

void userCode(Fred& fred, int memFnNum)


{
// Assume memFnNum is between 0 and 3 inclusive:
CALL_MEMBER_FN(fred, a[memFnNum]) ('x', 3.14);
}

3. Write a program to traverse an array using pointer.


Answer: #include <stdio.h>

int main()
{
int data[5], i;
printf ("Enter elements: ");

for(i = 0; i < 5; ++i)


scanf("%d", data + i);

printf("You entered: \n");


for(i = 0; i < 5; ++i)
printf("%d\n", *(data + i));

return 0;
}

Output

Enter elements: 1
2
3
5
4
You entered:
1
2
3
5
4

4. Write a program to compare two strings using pointer.


Answer:

1. #include<iostream>
2. #include<stdio.h>
3. using namespace std;
4. main() {
5. char str1[50],str2[50];
6. int str_cmp(char*,char*);
7. cout<<“Enter first string:”;
8. gets(str1);
9. cout<<“Enter second string:”;
10. gets(str2);
11. if(str_cmp(str1,str2))
12. cout<<“nStrings are equal”; else
13. cout<<“nStrings are not equal”;
14. return 0;
15.}
16.int str_cmp(char *s1,char *s2) {
17. while(*s1==*s2) {
18. if(*s1==’’||*s2==’’)
19. break;
20. s1++;
21. s2++;
22. }
23. if(*s1==’’&&*s2==’’)
24. return 1;
25. return 0;
26.}
Unit 12: Console I/O
1. Why should we use <iostream> instead of the traditional
<cstdio>?

Answer: Increase type safety, reduce errors, allow extensibility, and provide
inheritability.

printf() is arguably not broken, and scanf() is perhaps livable despite being error
prone, however both are limited with respect to what C++ I/O can do. C++ I/O
(using << and >>) is, relative to C (using printf() and scanf()):

 More type-safe: With <iostream>, the type of object being I/O'd is known
statically by the compiler. In contrast, <cstdio> uses "%" fields to figure
out the types dynamically.
 Less error prone: With <iostream>, there are no redundant "%" tokens
that have to be consistent with the actual objects being I/O'd. Removing
redundancy removes a class of errors.
 Extensible: The C++ <iostream> mechanism allows new user-defined
types to be I/O'd without breaking existing code. Imagine the chaos if
everyone was simultaneously adding new incompatible "%" fields to
printf() and scanf()?!
 Inheritable: The C++ <iostream> mechanism is built from real classes
such as std::ostream and std::istream. Unlike <cstdio>'s FILE*, these are
real classes and hence inheritable. This means you can have other user-
defined things that look and act like streams, yet that do whatever strange
and wonderful things you want. You automatically get to use the zillions
of lines of I/O code written by users you don't even know, and they don't
need to know about your "extended stream" class.

2. How can we get std::cin to skip invalid input characters?

Answer:
Use std: cin.clear () and std:: cin.ignore().

#include <iostream>
#include <limits>

int main()
{
int age = 0;

while ((std::cout << "How old are you? ")


&& !(std::cin >> age)) {
std::cout << "That's not a number; ";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

std::cout << "You are " << age << " years old\n";
...
}
Of course you can also print the error message when the input is out of range.
For example, if you wanted the age to be between 1 and 200, you could change
the while loop to:
...
while ((std::cout << "How old are you? ")
&& (!(std::cin >> age) || age < 1 || age > 200)) {
std::cout << "That's not a number between 1 and 200; ";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
...
Here's a sample run:
How old are you? foo
That's not a number between 1 and 200; How old are you? bar
That's not a number between 1 and 200; How old are you? -3
That's not a number between 1 and 200; How old are you? 0
That's not a number between 1 and 200; How old are you? 201
That's not a number between 1 and 200; How old are you? 2
You are 2 years old

3. Why does my input seem to process past the end of file?

Answer: Because the eof state may not get set until after a read is attempted
past the end of file. That is, reading the last byte from a file might not set the eof
state. E.g., suppose the input stream is mapped to a keyboard — in that case it's
not even theoretically possible for the C++ library to predict whether or not the
character that the user just typed will be the last character.
For example, the following code might have an off-by-one error with the count
i:

int i = 0;
while (! std::cin.eof()) { // WRONG! (not reliable)
std::cin >> x;
++i;
// Work with x ...
}
What you really need is:
int i = 0;
while (std::cin >> x) { // RIGHT! (reliable)
++i;
// Work with x ...
}

4. Why we should end the output lines with std::endl or ‘\n’?

Answer: sing std::endl flushes the output buffer after sending a '\n', which
means std::endl is more expensive in performance. Obviously if you need to
flush the buffer after sending a '\n', then use std::endl; but if you don't need to
flush the buffer, the code will run faster if you use '\n'.

This code simply outputs a '\n':

void f()
{
std::cout << ...stuff... << '\n';
}
This code outputs a '\n', then flushes the output buffer:
void g()
{
std::cout << ...stuff... << std::endl;
}
This code simply flushes the output buffer:
void h()
{
std::cout << ...stuff... << std::flush;
}

You might also like