What Is Virtual Function? Explain With An Example
What Is Virtual Function? Explain With An Example
A virtual function is a member function that is declared within a base class and redefined by a derived class. To create virt ual
function, precede the functions declaration in the base class with the keyword virtual. When a class containing virtual function is
inherited, the derived class redefines the virtual function to suit its own needs.
Base class pointer can point to derived class object. In this case, using base class pointer if we call some function which is in both
classes, then base class function is invoked. But if we want to invoke derived class function using base class pointer, it can be
achieved by defining the function as virtual in base class, this is how virtual functions support runtime polymorphism.
Consider following program code:
Class A
{
int a;
public:
A()
{
a = 1;
}
virtual void show()
{
cout <<a;
}
};
Class B: public A
{
int b;
public:
B()
{
b = 2;
}
virtual void show()
{
cout <<b;
}
};
int main()
{
A *pA;
B oB;
pA = &oB;
pA->show();
return 0;
}
Output is 2 since pA points to object of B and show () is virtual in base class A.
What is Operator Overloading in C++?
In C++ the overloading principle applies not only to functions, but to operators too. That is, of
operators can be extended to work not just with built-in types but also classes. A programmer can
provide his or her own operator to a class by overloading the built-in operator to perform some specific
computation when the operator is used on objects of that class. Is operator overloading really useful in
real world implementations? It certainly can be, making it very easy to write code that feels natural
(we'll see some examples soon). On the other hand, operator overloading, like any advanced C++
feature, makes the language more complicated. In addition, operators tend to have very specific
meaning, and most programmers don't expect operators to do a lot of work, so overloading operators
can be abused to make code unreadable.
Q. What is a friend function?
A friend function of a class is defined outside that class' scope but it has the right to access all private and protected members of
the class. Even though the prototypes for friend functions appear in the class definition, friends are not member functions.
A friend can be a function, function template, or member function, or a class or class template, in which case the entire class and all
of its members are friends.
To declare a function as a friend of a class, precede the function prototype in the class definition with keyword friend as follows:
class Box
{
double width;
public:
double length;
friend void printWidth( Box box );
void setWidth( double wid );
};
To declare all member functions of class ClassTwo as friends of class ClassOne, place a following declaration in the definiti on of
class ClassOne:
friend class ClassTwo;
Consider the following program:
#include <iostream>
using namespace std;
class Box
{
double width;
public:
friend void printWidth( Box box );
void setWidth( double wid );
};
// Member function definition
void Box::setWidth( double wid )
{
width = wid;
}
// Note: printWidth() is not a member function of any class.
void printWidth( Box box )
{
/* Because setWidth() is a friend of Box, it can
directly access any member of this class */
cout << "Width of box : " << box.width <<endl;
}
// Main function for the program
int main( )
{
Box box;
// set box width without member function
box.setWidth(10.0);
// Use friend function to print the wdith.
printWidth( box );
return 0;
}
When the above code is compiled and executed, it produces the following result:
Width of box : 10
What is File mode in C++? Describe the various file mode options available.
Data Type Description
ofstream
This data type represents the output file stream and is used to create
files and to write information to files.
ifstream
This data type represents the input file stream and is used to read
information from files.
fstream
This data type represents the file stream generally, and has the
capabilities of both ofstream and ifstream which means it can create
files, write information to files, and read information from files.
To perform file processing in C++, header files <iostream> and <fstream> must be included in your C++ source file.
Opening a File:
A file must be opened before you can read from it or write to it. Either the ofstream or fstream object may be used to open a file for writing and ifstream object is used to
open a file for reading purpose only.
Following is the standard syntax for open() function, which is a member of fstream, ifstream, and ofstream objects.
void open(const char *filename, ios::openmode mode);
Here, the first argument specifies the name and location of the file to be opened and the second argument of the open() member function defines the mode in which the
file should be opened.
Mode Flag Description
ios::app Append mode. All output to that file to be appended to the end.
ios::ate
Open a file for output and move the read/write control to the end of the
file.
ios::in Open a file for reading.
ios::out Open a file for writing.
ios::trunc
If the file already exists, its contents will be truncated before opening
the file.
You can combine two or more of these values by ORing them together. For example if you want to open a file in write mode and want to truncate it in case it already
exists, following will be the syntax:
ofstream outfile;
outfile.open("file.dat", ios::out | ios::trunc );
Similar way, you can open a file for reading and writing purpose as follows:
fstream afile;
afile.open("file.dat", ios::out | ios::in );
Closing a File
When a C++ program terminates it automatically closes flushes all the streams, release all the allocated memory and close all the opened files. But it is always a good
practice that a programmer should close all the opened files before program termination.
Following is the standard syntax for close() function, which is a member of fstream, ifstream, and ofstream objects.
void close();
Writing to a File:
While doing C++ programming, you write information to a file from your program using the stream insertion operator (<<) just as you use that operator to output
information to the screen. The only difference is that you use an ofstream or fstream object instead of the cout object.
Reading from a File:
You read information from a file into your program using the stream extraction operator (>>) just as you use that operator to input information from the keyboard. The
only difference is that you use an ifstreamor fstream object instead of the cin object.
Read & Write Example:
Following is the C++ program which opens a file in reading and writing mode. After writing information inputted by the user to a file named afile.dat, the program reads
information from the file and outputs it onto the screen:
#include <fstream>
#include <iostream>
using namespace std;
int main ()
{
char data[100];
// open a file in write mode.
ofstream outfile;
outfile.open("afile.dat");
cout << "Writing to the file" << endl;
cout << "Enter your name: ";
cin.getline(data, 100);
// write inputted data into the file.
outfile << data << endl;
cout << "Enter your age: ";
cin >> data;
cin.ignore();
// again write inputted data into the file.
outfile << data << endl;
// close the opened file.
outfile.close();
// open a file in read mode.
ifstream infile;
infile.open("afile.dat");
cout << "Reading from the file" << endl;
infile >> data;
// write the data at the screen.
cout << data << endl;
// again read the data from the file and display it.
infile >> data;
cout << data << endl;
// close the opened file.
infile.close();
return 0;
}
When the above code is compiled and executed, it produces the following sample input and output:
$./a.out
Writing to the file
Enter your name: Zara
Enter your age: 9
Reading from the file
Zara
9
Above examples make use of additional functions from cin object, like getline() function to read the line from outside and ignore()
function to ignore the extra characters left by previous read statement.
Q. Compare between procedural programming and OOP.
Object oriented programming
In object oriented programming, the data and related functions are bundled together into an "object". Ideally, the data inside an
object can only be manipulated by calling the object's functions. This means that your data is locked away inside your objects and
your functions provide the only means of doing something with that data. In a well designed object oriented system objects never
access shared or global data, they are only permitted to use the data they have, or data they are given.
Global and shared data
We can see that one of the principle differences is that procedural systems make use of shared and global data, while object
oriented systems lock their data privately away in objects.
Let's consider a scenario where you need to change a shared variable in a procedural system. Perhaps you need to rename it,
change it from a string to a numeric, change it from a struct to an array, or even remove it completely.
In a procedural application you would need to find and change each place in the code where that variable is referenced. In a large
system this can be a widespread and difficult change to make.
In an object oriented system we know that all variables are inside objects and that only functions within those objects can access or
change those variables. When a variable needs to be changed then we only need to change the functions that access those
variables. As long as we take care that the functions' input arguments and output types are not changed, then we don't need to
change any other part of the system.
The cost of OOP
Object oriented design is complicated to do well, and a substantial amount of time is likely to be required to learn it in depth. If you
have been developing procedural systems for some time then object oriented concepts will require learning a different way of
thinking which is always challenging and requires effort.
However the time to learn is not the only cost. Once you start learning, you may start to question yourself time and time again if you
are writing code "correctly". Your productivity may be affected as you try different ideas, aiming for a good object oriented solution.
A further cost to consider is not specific to OO, but is specific to OO within ColdFusion. You may read many object oriented articles
and books but you cannot apply their teachings blindly in your ColdFusion applications. There is a performance factor associated
with creating objects in ColdFusion so applying many of the pure object oriented ideas can adversely affect your application. This
then adds an additional challenge in knowing when not to apply some object oriented ideas.
Q. Write down the functions of different linking loader.
Linking Functions
First, let understand what linking means and why it is necessary. Software is made up of instructions grouped in logical sections
called subroutines or functions. Most functions perform a specific task based on a set of input and output variables. These
individual functions are able to use or call each other using a process called linking.
Calling one function from another function is based on knowing the address or location of each function. Once this address is
known, the calling function executes or passes control to the called function. When the called function completes, control is
returned to the calling function.
Linking is simply the process of placing the address of a called function into the calling function's code. This is a fundamental
software concept.
Now consider a function F contains a call to a function H, and suppose that these two functions were defined in the same
module (informally, the same *.cpp file). In this case, the linking between the call to H in F, and the address of H can be done
by compiler, since both functions are given to it at the same compilation session. Well, this is nice and simple, but it is not always
the case when the modularity is a part of our programming life.
Suppose that the functions F and H are defined in two different modules M(F) and M(H). In this case, the compiler can not
resolve the problem of linking between the call to H in F, and the address of H. Note that the this situation is always the case if
the function H was not written by us, but, for example, is a part of a library of functions that was created for general use. For
example, in our C code, we are using the function socket(...)which is definitely was not written by us.
In this case, some linking should be done after the separate compiling of the modules by a linker.
In general, there are three types of linkers:
Static Linker (or linkage editor) - linking prior to load time.
Implicit Dynamic Linker (or linking loader) - linking at load time.
Explicit Dynamic Linker - linking is performed at execution time.
Static Linking
The simplest form of linking is called static linking.
Static linking is used to combine multiple functions into a single object module. These functions may be a part of your compiled
program modules, and/or a part of various archive libraries that it uses. The result of static linking may be either an executable
object, or an archive library. The notion of executable object is pretty intuitive -- an executable object contains specification of a
process (or, informally, you can "run" it). The notion of archive library is novel and well-known for you at the same time -- until
now, you never created one, but you used them many times. For example, if you are giving -lsocket as a parameter to your
linking command (see your Makefile for the Connector component in the third assignment), then you explicitly specify to your
linking to look for the unresolved references in the libsocket.a archive library.
As we said, the linker is given your compiled code, containing many unresolved references to library routines. It also gets archive
libraries (for example /usr/lib/libm.a) containing each library routine as a separate module. The linker keeps working
until there are no more unresolved references and writes out a single file that combines your code and a jumbled mixture of
modules containing parts of several libraries. The library routines make system calls directly, so a statically linked application is
built to work with the kernel's system call interface.
This static linking process takes place once - when the executable module is created. All internal references to functions within a
module are resolved at this time. In some cases, an entire application is built out of a single statically linked executable module.
In this case, the resulting module is an autonomous unit that can execute without referencing any other modules.
Now, let present the advantages and disadvantages of the static linking:
Advantages
o One linking for many executions.
o Calls into the library routines have a little less overhead since they are linked together directly.
o Start-up time at program loading is reduced as there is no need to locate and load the dynamic libraries.
o Possibility to create archive libraries is unique for static linking.
Disadvantages
o Physical memory wasted by duplicating the same library code in every static linked process can be significant.
For example, if all the window system tools were statically linked, several tens of megabytes of physical
memory would be wasted for a typical user, and the user would be slowed down by a lot of paging.
o Subsequent versions of the operating system contain better-tuned and debugged library routines, or routines
that enable new functionality. Static linking locks in the old slow or buggy routines and prevents access to the
new functionality.
o A static-linked program contains a subset of the jumbled library routines. The library cannot be tuned as a
whole to put routines that call each other onto the same memory page. The whole application could be tuned
this way, but very few developers take the trouble.
o During program development, recompiling for nearly every execution. As far as we are talking about
developing an assignment for our course, this may be not so important parameter. However, if compiling of a
product that has been developed is taking the whole night, then it the picture is completely different.
o Since the size of the executable object may be relatively large, the storage waste is significant, especially in
case of infrequently used program.
Dynamic Linking
A second way to link functions together is through a process called dynamic linking. With dynamic linking, executable modules
created by static linking can contain references to functions in other modules. All modules that reference each other must be
linked together dynamically when they are executed. Thus the term dynamic linking.
The central property of the dynamic linking is that even if many processes are using a particular, dynamically linked function,
only a SINGLE copy of this function appears in the memory, and it is shared by all these processes.
The dynamic linking process consists of two steps. First, the module that contains the external function must be located. Second,
the address of the function within this module must be found. Once this address is found, the calling module can use this external
function just as if it was linked statically.
Dynamically imported functions are functions that are called from within one module but actually reside in another module. In
order to import a function, the developer must provide the name of the module and the function name. These two items should
uniquely identify the imported function.
Dynamic linking occurs when this information is used to find the imported function's address. If the specified module is found, its
headers are examined for the desired function name. If the specified function is also found, its address is dynamically placed in the
calling module's code.
There are two dynamic linking methods:
Implicit Dynamic Linking
Explicit Dynamic Linking
Implicit Dynamic Linking
With implicit dynamic linking, the process of identifying imported functions is handled automatically by operating system at
runtime. When using implicit dynamic linking, the importing module contains header fields for each implicitly imported function.
These header fields are generated by a static linker, and each one of them contain the exporting module and imported function
name. The static linker also adds to the executable object a start-up code to load the required libraries to the memory at
runtime (if they are still not there!), and each library call goes through a jump table. The first time a routine is actually called, the
jump table is patched to point at the library routine. For subsequent calls, the only overhead is the indirect reference.
Data Structure: Implementation of Queue in C++
queue is an order collection of items from which items may be deleted at one end (called front or head of the queue)
and into which items may be inserted at the other end (called the rear end or tail of the queue). It is First-in-First-out
(FIFO) type of data structure. Operations on queue are: Create Queue, insert items , remove items, display etc.
Algorithm for Implementation of Queue in C++
1. Declare and initialize neccessary variables, front = 0, rear = -1 etc.
2. For enque operation,
If rear >= MAXSIZE - 1
print "Queue is full"
Else
- Increment rear by 1 i.e. rear = rear + 1;
- queue[rear] = item;
3. For next enqueue operation, goto step 2.
4. For dequeue operation
If front > rear
print "Queue is Empty"
Else
- item = queue[front]
- increment front by 1 i.e. front = front + 1
5. For dequeue next data items, goto step 4.
6. Stop
Example :
#include<iostream>
#include<cstdlib>
#define MAX_SIZE 10
using namespace std;
class Queue{
private:
int item[MAX_SIZE];
int rear;
int front;
public:
Queue();
void enqueue(int);
int dequeue();
int size();
void display();
bool isEmpty();
bool isFull();
};
Queue::Queue(){
rear = -1;
front = 0;
}
void Queue::enqueue(int data){
item[++rear] = data;
}
int Queue::dequeue(){
return item[front++];
}
void Queue::display(){
if(!this->isEmpty()){
for(int i=front; i<=rear; i++)
cout<<item[i]<<endl;
}else{
cout<<"Queue Underflow"<<endl;
}
}
int Queue::size(){
return (rear - front + 1);
}
bool Queue::isEmpty(){
if(front>rear){
return true;
}else{
return false;
}
}
bool Queue::isFull(){
if(this->size()>=MAX_SIZE){
return true;
}else{
return false;
}
}
int main(){
Queue queue;
int choice, data;
while(1){
cout<<"\n1. Enqueue\n2. Dequeue\n3. Size\n4. Display all element\n5. Quit";
cout<<"\nEnter your choice: ";
cin>>choice;
switch(choice){
case 1:
if(!queue.isFull()){
cout<<"\nEnter data: ";
cin>>data;
queue.enqueue(data);
}else{
cout<<"Queue is Full"<<endl;
}
break;
case 2:
if(!queue.isEmpty()){
cout<<"The data dequeued is :"<<queue.dequeue();
}else{
cout<<"Queue is Emtpy"<<endl;
}
break;
case 3:
cout<<"Size of Queue is "<<queue.size();
break;
case 4:
queue.display();
break;
case 5:
exit(0);
break;
}
}
return 0;
}
Q. What is Virtual base class? Explain its uses.
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.
Consider following example:
class A
{
public:
int i;
};
class B : virtual public A
{
public:
int j;
};
class C: virtual public A
{
public:
int k;
};
class D: public B, public C
{
public:
int sum;
};
int main()
{
D ob;
ob.i = 10; //unambiguous since only one copy of i is inherited.
ob.j = 20;
ob.k = 30;
ob.sum = ob.i + ob.j + ob.k;
cout << Value of i is : << ob.i<<\n;
cout << Value of j is : << ob.j<<\n; cout << Value of k is :<< ob.k<<\n;
cout << Sum is : << ob.sum <<\n;
return 0;
}