Good Questions In
C++
!!Enjoy!!!
52.
Can we return an error value from the constructor of a class?
Ans: No. We cannot return any error value from the
constructor, as the constructor doesn't have any return type.
However, by throwing an exception we can pass value to catch
block. This is shown in the following example:
#include <iostream.h>
class sample
{
public :
sample ( int i )
{
if ( i == 0 )
throw "error" ;
}
} ;
void main( )
{
try
{
sample s ( 0 ) ;
}
catch ( char * str )
{
cout << str ;
}
}
In this program, the statement throw "error" ; would throw an
exception when an object s of the class sample would get
created. The catch block would collect the string error.
-------------------------------------------------------------------------------------------------
53.
How do I define the member function of a template class, which
has to be defined outside the template class. The function
receives an object of its own class as a parameter and returns
the value of the same type.
Ans: The following example shows how we can define such a
function.
sample <T> sample<T>::fun ( sample s )
{
// code
}
Here, the first sample<T> indicates the return type of the
function and the next sample<T> is used for the scope of
function.
-------------------------------------------------------------------------------------------------
54.
How name mangling can be prevented?
Ans: To avoid name mangling the function should be declared
with an extern "C" attribute. Functions declared as extern "C"
are treated as C-style functions. Hence the compiler does not
mangle them. The following code snippet shows how to declare
such a function.
#include <iostream.h>
extern "C" void display( )
{
cout << "See the effect of C in C++ " ;
}
void main( )
{
display( ) ;
}
-------------------------------------------------------------------------------------------------
55.
Can we allocate memory dynamically for a reference?
Ans: No, it is not possible to allocate memory dynamically for
a reference. A reference is initialized at the time of
creation. Trying to allocate memory dynamically for a
reference creates a problem in initializing it. Thus, the
compiler does not allow us to dynamically allocate the memory
for references.
-------------------------------------------------------------------------------------------------
56.
What is RTTI?
Ans: RTTI stands for 'Run Time Type Information'. We use
virtual function mechanism where we can call derived class's
member functions using base class's pointer. However, many
times we wish to know the exact type of the object. We can
know the type of the object using RTTI. A function that
returns the type of the object is known as RTTI functions. C++
supports two ways to obtain information about the object's
class at run time, they are typeid( ) operator and
dynamic_cast operator.
-------------------------------------------------------------------------------------------------
57.
What is Data Conversion?
Ans: Assignments between types whether they are basic or
user-defined, are handled by the compiler. If the variables
are of different basic types compiler calls a special routine
to convert the value. But if we want to convert between
user-defined data type and basic types we have to write
conversion routine ourselves. A conversion routine to convert
user-defined data type string to integer is shown below:
class string
{
private :
char str[20] ;
public :
string( )
{
}
string ( char *s )
{
strcpy ( str, s ) ;
}
operator int( )
{
return 123 ; // Write logic to convert string to integer
}
} ;
main( )
{
string s2 = "123" ;
int i1 = int ( s2 ) ;
cout << endl << i1 ;
}
-------------------------------------------------------------------------------------------------
58.
How to obtain type information using typeid( ) operator?
Ans: typeid( ) operator takes an object, a reference or a
pointer and returns its type. Following program shows how to
use the typeid( ) operator.
#include <iostream.h>
#include <typeinfo.h>
class Base
{
public :
virtual void show( )
{
}
};
class Der1 : public Base
{
} ;
void main( )
{
Base *b1 ;
cout << endl << typeid ( b1 ).name( ) ;
Der1 d1 ;
b1 = &d1 ;
cout << endl << typeid ( *b1 ).name( ) ;
cout << endl << typeid ( 12 ).name( ) << endl << typeid ( 12.5
).name( ) ;
}
The output of this program will be
Base*
Der1
int
double
RTTI operators must be used for polymorphic class (class
having virtual function) only. For non-polymorphic class
static type information is returned.
-------------------------------------------------------------------------------------------------
59.
How to use RTTI with class templates?
Ans: Templates can generate different classes. We may wish to
get the type of class, which we are working in. The following
program shows how to use RTTI operator typeid( ) with class
template.
#include <iostream.h>
#include <typeinfo.h>
template <class T>
class base
{
public :
base( )
{
cout << typeid ( *this ).name( ) << "Constructor" << endl ;
}
T add ( T a, T b )
{
return a + b ;
}
~base( )
{
cout << typeid ( *this ).name( ) << "Destructor" << endl ;
}
} ;
void main( )
{
base <int> b1 ;
cout << b1.add ( 10, 20 ) << endl ;
base <float> b2 ;
cout << b2.add ( 5.5, 10.5 ) << endl ;
}
-------------------------------------------------------------------------------------------------
60.
We can use following C++ operators for typecasting.static_cast
is used for castless conversions, narrowing conversions,
conversion from void* and implicit type conversions.
const_cast is used to convert a const to a non-const.
reinterpret_cast is used to assign one kind of pointer to
another.
-------------------------------------------------------------------------------------------------
61.
What will be the output of the following program?
#include <iostream.h>
class A
{
public :
A( )
{
cout << "Reached in Constructor\n" ;
}
} ;
void main( )
{
A a( ) ;
A b ;
}
Output : Reached in Constructor
Constructor gets called only once when the object b is
created. When the statement A a( ) ; gets executed constructor
does not get called. This is because compiler takes this
statement as a prototype declaration of function a( ) that
returns an object of class A. However, if we pass arguments
like
A a ( 10 ) ;
Compiler would search for one argument constructor and if not
found would flash an error.
-------------------------------------------------------------------------------------------------
62.
What is a container?
Ans: A container is an object that holds other objects.
Various collection classes like List, Hash Table,
AbstractArray, etc. are the examples of containers. We can use
the classes to hold objects of any derived classes. The
containers provide various methods using which we can get the
number of objects stored in the container and iterate through
the objects stored in it.
-------------------------------------------------------------------------------------------------
63.
Function template overloading
One can declare several function templates with the same name
and even declare a combination of function templates and
ordinary functions with the same name. When an overloaded
function is called, overload resolution is necessary to find
the right function or template function to invoke.
For example:
template < class T > T sqrt ( T ) ;
template < class T > complex < T > sqrt ( complex < T > )
;double sqrt (
double ) ;
void f ( complex < double > z )
{
sqrt ( 2 ) ; // sqrt < int > ( int )
sqrt ( 2.0 ) ; // sqrt ( double )
sqrt ( z ) ; // sqrt < complex < double > ( complex < double >
)
}
In the same way that a template function is a generalization
of the notion of a function, the rules for resolution in the
presence of function templates are generalizations of the
function overload resolution rules. Basically, for each
template we find the specialization that is best for the set
of function arguments. Then we apply the usual function
overload resolution rules to these specializations and all
ordinary functions.
-------------------------------------------------------------------------------------------------
64.
Exception Handling in C++
In C++ we can handle run-time errors generated by c++ classes
by using three new keywords: throw, catch, and try. We also
have to create an exception class. If during the course of
execution of a member function of
this class a run-time error occurs, then this member function
informs the application that an error has occurred. This
process of informing is called 'throwing' an exception. The
following code shows how to deal with exception handling.
class sample
{
public :
class errorclass
{
} ;
void fun( )
{
if ( some error occurs )
throw errorclass( ) // throws exception
}
} ;
//application
void main( )
{
try
{
sample s ;
s.fun( ) ;
}
catch ( sample::errorclass )
{
// do something about the error
}
}
-------------------------------------------------------------------------------------------------
65.
Consider the following code:
#include <iostream.h>
class base
{
public :
int data ;
} ;
class d1 : public base
{
} ;
class d2 : public base
{
} ;
class der : public d1, public d2
{
public :
void showdata( )
{
cout << data ;
}
} ;
void main( )
{
der d ;
d.showdata( ) ;
}
If you run this program it is bound to give you errors. This
is because of the rules of inheritance:
1. Each base class not specified virtual will have its own
sub-object representing it. In the above program, if we create
object of d1 it will have a sub-object of class base
containing a data member data. If we create an object of class
der it will have sub-objects of classes d1 and d2 and both the
sub-objects will refer to a separate copy of data. Hence, to
access data from class der we will have to mention the class
name. For example, d1::data or d2::data.
2. If we want that only one sub-object should exist we must
use the concept of virtual base class. The single object of
this will represent every base class of given name that is
specified to be virtual
class. After making d1 and d2 as virtual base class if we
create an object of der only one sub-object would exist and so
accessing data would no longer give us errors.
-------------------------------------------------------------------------------------------------
66.
How to declare a pointer to a member function?
Ans: Suppose, I wish to declare a pointer to a member function
that receives an int and returns an int. I will have to
declare it as int (A::* ) ( int ). Following is an example.
#include <iostream.h>
class A
{
public :
int fun ( int f )
{
cout << "in fun\n" ;
return f * f ;
}
} ;
typedef int ( A:: *pfun ) ( int ) ;
void main( )
{
pfun p = A::fun ;
A a ;
int s = ( a.*p ) ( 6 ) ;
cout << s ;
}
-------------------------------------------------------------------------------------------------
67.
What is the disadvantage of a template function?
Ans: A template function cannot be distributed in the obj
form. This is because, with which parameters the template
function is going to be called is decided at the run time
only. Therefore an obj form of a template function cannot be
made by merely compiling it.
-------------------------------------------------------------------------------------------------
68.
How to declare a pointer to the data members of a class?
Ans: Following program shows how to declare a pointer to
non-function members of a class.
#include <iostream.h>
class A
{
public :
int a ;
void print( )
{
cout << a ;
}
} ;
void main( )
{
int A::*pa = &A::a ;
A obj ;
obj.*pa = 20 ;
obj.print( ) ;
}
Here, we have initialised the data member a using the pointer
pa.
-------------------------------------------------------------------------------------------------
69.
How to allocate memory for a multidimensional array
dynamically?
Ans: Many times we need to allocate memory for a
multidimensional array dynamically. Because of complexity of
pointers many find this difficult. Following program allocates
memory for a 3 x 3 array dynamically, copies contents of a 3 x
3 array in it and prints the contents using the pointer.
#include <iostream.h>
#include <new.h>
int a[ ][3] = {
1, 2, 3,
4, 5, 6,
7, 8, 9
} ;
void main( )
{
int **p ;
p = new int *[3] ;
for ( int i = 0 ; i < 3 ; i++ )
p[i] = new int[3] ;
for ( i = 0 ; i < 3 ; i++ )
for ( int j = 0 ; j < 3 ; j++ )
p[i][j] = a[i][j] ;
for ( i = 0 ; i < 3 ; i++ )
{
for ( j = 0 ; j < 3 ; j++ )
cout << p[i][j] ;
cout << "\n" ;
}
}
-------------------------------------------------------------------------------------------------
70.
When should we use the :: ( scope resolution ) operator to
invoke the virtual functions?
Ans: Generally, :: operator is used to call a virtual function
from constructor or destructor. This is because, if we call a
virtual function from base class constructor or destructor the
virtual function of the base class would get called even if
the object being constructed or destroyed would be the object
of the derived class. Thus, whenever we want to bypass the
dynamic binding mechanism we must use the :: operator to call
a virtual function.
-------------------------------------------------------------------------------------------------
71.
How do I use operators .* and ->* in a program?
Ans: The following code snippet demonstrates the use of .* and
->* operators.
#include <iostream.h>
class sample
{
public :
int i ;
void fun( )
{
cout << "fun" << endl ;
}
} ;
void ( sample::*pf )( ) = &sample::fun ;
int sample::*pdm = &sample::i ;
void main( )
{
sample s ;
sample *p = new sample ;
( s .* pf )( ) ;
( p ->* pf )( ) ;
s .* pdm = 1 ;
p ->* pdm = 2 ;
cout << s .* pdm << endl ;
cout << p ->* pdm << endl ;
}
In the above program pf is a pointer to a function fun( ) of
class sample, and pdm is a pointer to a data member i of the
same class sample. The object s of the class sample is created
statically. Next, p is a pointer to an object created
dynamically. The using the operator .* and ->* the member
functions are called and also the public data member is
accessed.
-------------------------------------------------------------------------------------------------
72.
What happens when we add an int value to a user defined type
of object?
Ans: Whenever an int value is added to an object of user
defined type, the object would search for an overloaded
operator int( ). This operator must be defined in such a way
that it always returns an int value. However, we need not
specify the return type as on doing so the compiler flashes an
error.
#include <iostream.h>
class sample
{
int i ;
public :
sample ( )
{
i = 10 ;
}
operator int( )
{
return this -> i ;
}
} ;
void main( )
{
sample s ;
int i ;
i = s + 10 ;
cout << i ;
}
In the above program on adding 10 to an object s, the value of
i would become 20.
-------------------------------------------------------------------------------------------------
73.
Can we have a reference to an array?
Ans: Yes, we can have a reference to an array.
int a[ ] = { 8, 2, 12, 9 } ;
int ( &r ) [ 4 ] = a ; // reference to an array
Here, r is a reference to an array of four elements. We can
even print the elements of array with the help of reference.
This is shown in the following code segment:
for ( int i = 0 ; i < 4 ; i++ )
cout << r [i] << endl ;
-------------------------------------------------------------------------------------------------
74.
When friend function becomes indispensable...
Ans: Consider the following program.
#include <iostream.h>
class distance
{
private :
int feet ;
public :
distance( )
{
feet = 0 ;
}
distance ( int f )
{
feet = f ;
}
distance operator + ( distance x )
{
int f = feet + x.feet ;
return distance ( f ) ;
}
} ;
void main( )
{
distance d1 ( 20 ), d2, d3 ;
d2 = d1 + 10 ;
d3 = 10 + d2 ;
}
If you run this program it is bound to give errors. The error
lies in the statement d3 = 10 + d2 ; We may think that since
we have overloaded + operator this statement would add 10 to
d2. But this does not happen. This is because the specified
statement will get converted as d3 = 10.operator+ ( d2 ) ;
This means that this statement should call the operator+( )
function that takes an object of distance class as parameter
written in
the float class, which is not possible. The solution is to
write operator+( ) as a 'friend' function. Declare operator+
function in distance class as given below:
friend distance operator + ( distance x1, distance x2 ) ;
and define it outside the class as shown below:
distance operator + ( distance x1, distance x2 )
{
int f = x1.feet + x2.feet ;
return distance ( f ) ;
}
When compiler would see that the 'friend' operator+( )
function is available it would convert the statement d3 = 10 +
d2 as operator+ (10, d2 ). Now since 10 is passed as a
parameter not as a calling object there would be no error.
Thus in such cases 'friend' function becomes indispensable.
-------------------------------------------------------------------------------------------------
75.
How to use a memory as a stream?
Ans: Suppose, details of an employee such as name,
designation, age, etc. are stored in different types of
variables. Now, if we wish to concatenate these details in a
character array we will have to use various string
manipulation functions like strcpy( ) and strcat( ). Instead
of using these functions we can use more easy and clean way to
gather the details in the char array in the form of streams.
We can declare the memory allocated for the array as stream
and use the << operator to store variables having different
types in this memory. Following program shows how to achieve
this.
#include<strstream.h>
void main( )
{
char buff [50] ;
char str[ ] = "Sanjay" ;
char desig[ ] = "Manager" ;
char jd[ ] = "27/12/1995" ;
int age = 35 ;
ostrstream o ( buff, sizeof ( buff ) ) ;
o << str << endl << desig << endl << jd << endl << age << ends
;
cout << buff ;
}
As shown in the program we can also use the manipulators and
formatting flags. The output of this program will be:
Sanjay
Manager
27/12/1995
35
-------------------------------------------------------------------------------------------------
76.
How would you declare and initialize reference to a data
member?
Ans: Sometimes we may need to declare a data member, which is
a reference to another data member of the class as shown
below:
class A
{
public :
char *p ;
char *&rp ;
} ;
We can't initialize a reference to a data member at the time
of declaration. It should be initialized using 'member wise
initialization as shown below.
#include <iostream.h>
class A
{
public :
char *p ;
char *&rp ;
A( ) : rp ( p )
{
p = "" ;
}
A ( char *s ) : rp ( p )
{
p = s ;
}
} ;
void main( )
{
A a ( "abcd" ) ;
cout << a.rp ;
}
-------------------------------------------------------------------------------------------------
77.
iostream library has made it easy to read data from various
input devices and write data to the output devices. The
following program shows how to print a disk file 'data.dat' on
the printer using stream classes. Every hardware device has a
familiar name given by the operating system. The printer is
generally connected to the first parallel port. So, the file
name for the printer should be PRN or lpt1.
#include <fstream.h>
void main( )
{
ifstream i ( "data.dat" ) ;
ofstream o ;
o.open ( "PRN" ) ;
char ch ;
while ( 1 )
{
i.get ( ch ) ;
if ( i.eof( ) )
break ;
o.put ( ch ) ;
}
o.put ( '\x0C' ) ;
}
-------------------------------------------------------------------------------------------------
78.
We know that a destructor is automatically called when an
object of a class goes out of scope. There is another case
where destructor is called automatically. If an object is
created in a try block and an exception is thrown after the
object is created, then the destructor is called
automatically.
-------------------------------------------------------------------------------------------------
79.
Can a function call be at the left hand side of the assignment
operator?
Ans: Yes. Following program shows how it is possible.
#include <iostream.h>
class ref
{
private :
struct data
{
int a ; char *p ;
} d1, d2 ;
public :
data &set ( )
{
return d1 ;
}
data &get ( )
{
cin >> d2.a >> d2.p ;
return d2 ;
}
} ;
void main( )
{
ref r ;
r.set( ) = r.get( ) ;
r.print( ) ;
}
In the above program the functions get( ) and set( ) both
return a reference to the object of the structure data. We
have assigned the reference returned by get( ) to the
reference returned by set( ) function. That is, we are
assigning d2 to d1. So, the values of d2 would get assigned to
d1. You can check this out by printing the values of d1.
-------------------------------------------------------------------------------------------------
80.
If a class contains a virtual function a pointer called VPTR
is created. This VPTR becomes a part of every object of that
class. The first two bytes (in DOS) are occupied by VPTR. We
can prove this by displaying the first two bytes of memory
allocated for the objects. Following program shows how this
can be achieved.
#include <iostream.h>
class vir
{
public :
virtual void f( )
{
}
} ;
void main( )
{
vir v, v1 ;
int *p1 = ( int* ) &v ;
int *p2 = ( int* ) &v1 ;
cout << endl << *p1 << " " << *p2 ;
}
-------------------------------------------------------------------------------------------------
81.
Exception Handling in C++
In C++ we can handle run-time errors generated by c++ classes
by using three new keywords: throw, catch, and try. We also
have to create an exception class. If during the course of
execution of a member function of
this class a run-time error occurs, then this member function
informs the application that an error has occurred. This
process of informing is called 'throwing' an exception. The
following code shows how to deal with exception handling.
class sample
{
public :
class errorclass
{
} ;
void fun( )
{
if ( some error occurs )
throw errorclass( ) // throws exception
}
} ;
//application
void main( )
{
try
{
sample s ;
s.fun( ) ;
}
catch ( sample::errorclass )
{
// do something about the error
}
}
-------------------------------------------------------------------------------------------------
82.
Accessing a private data member from a different Object...
Different objects of the same class can access each other's
members, even if these members are private. For example:
#include < iostream.h >
class sample
{
float f ;
public :
sample ( float ff )
{
f = ff ;
}
void fun ( sample* objptr )
{
objptr -> n = 0 ;
cout << "Value of this objects f is : " << f << endl ;
cout << "Value of other objects f" << objptr -> n << endl ;
} // another object's private member!
} ;
void main( )
{
sample s1 ( 6.5f ) , s2 ( 2.5f ) ;
s1.f ( &s2 ) ; // s1 changes s2's n
}
Typically, this coding style should be avoided. However, you
should be aware that private members of an object can be
changed by another object of the same type. Therefore, in
certain special conditions, this coding style may be useful.
-------------------------------------------------------------------------------------------------
83.
Can you access private data members of a class from out side
the class?
Ans: Yes. This program shows how.
#include <iostream.h>
class emp
private :
int i ;
public :
emp( )
{
i = 10 ;
}
} ;
void main( )
emp *p = new emp ;
int *pi = (int*) p ;
cout << *pi ;
*pi = 20 ;
cout << *pi ;
}
The pointer to the class is typecasted in an integer pointer.
With the help of this pointer private data member 'i' is
accessed in main( ).
-------------------------------------------------------------------------------------------------
84.
Why creating array of references is not possible?
Ans: The array name always refers or points to the zeroeth
element. If array is of references then the array name would
point to the zeroeth element which happens to be a reference.
Creating pointer to a reference is not valid. So, creating
array of references too is not possible.
-------------------------------------------------------------------------------------------------