(Paper) C++ Programming tips &Technical Interview Questions Source code examples Set-4
Paper : C++ Programming tips &Technical Interview Questions Source code examples Set-4
31.Can I
have a reference as a data member of a class? If yes, then how do I initialise
it?
Ans: Yes, we can have a reference as a data member of a class. A reference as a
data member of a class is initialised in the initialisation list of the
constructor. This is shown in following program.
#include
class sample
{
private :
int& i ;
public :
sample ( int& ii ) : i ( ii )
{
}
void show( )
{
cout << i << endl ;
}
} ;
void main( )
{
int j = 10 ;
sample s ( j ) ;
s.show( ) ;
}
Here, i refers to a variable j allocated on the stack. A point to note here is
that we cannot bind a reference to an object passed to the constructor as a
value. If we do so, then the reference i would refer to the function parameter
(i.e. parameter ii in the constructor), which would disappear as soon as the
function returns, thereby creating a situation of dangling reference.
-------------------------------------------------------------------------------------------------
32.Why does the following code fail?
#include
class sample
{
private :
char *str ;
public :
sample ( char *s )
{
strcpy ( str, s ) ;
}
~sample( )
{
delete str ;
}
} ;
void main( )
{
sample s1 ( "abc" ) ;
}
Ans: Here, through the destructor we are trying to deal locate memory, which has
been allocated statically. To remove an exception, add following statement to
the constructor.
sample ( char *s )
{
str = new char[strlen(s) + 1] ;
strcpy ( str, s ) ;
}
Here, first we have allocated memory of required size, which then would get deal
located through the destructor.
-------------------------------------------------------------------------------------------------
33. assert( ) macro...
We can use a macro called assert( ) to test for conditions that should not occur
in a code. This macro expands to an if statement. If test evaluates to 0, assert
prints an error message and calls abort to abort the program.
#include
#include
void main( )
{
int i ;
cout << "\nEnter an integer: " ;
cin >> i ;
assert ( i >= 0 ) ;
cout << i << endl ;
}
34. Why it
is unsafe to deal locate the memory using free( ) if it has been allocated using
new?
Ans: This can be explained with the following example:
#include
class sample
{
int *p ;
public :
sample( )
{
p = new int ;
}
~sample( )
{
delete p ;
}
} ;
void main( )
{
sample *s1 = new sample ;
free ( s1 ) ;
sample *s2 = ( sample * ) malloc ( sizeof ( sample
) ) ;
delete s2 ;
}
The new operator allocates memory and calls the constructor. In the constructor
we have allocated memory on heap, which is pointed to by p. If we release the
object using the free( ) function the object would die but the memory allocated
in the constructor would leak. This is because free( ) being a C library
function does not call the destructor where we have deal located the memory.
As against this, if we allocate memory by calling malloc( ) the constructor
would not get called. Hence p holds a garbage address. Now if the memory is deal
located using delete, the destructor would get called where we have tried to
release the memory pointed to by p. Since p contains garbage this may result in
a runtime error.
-------------------------------------------------------------------------------------------------
35.Can we distribute function templates and class templates in object
libraries?
Ans: No! We can compile a function template or a class template into object code
(.obj file). The code that contains a call to the function template or the code
that creates an object from a class template can get compiled. This is because
the compiler merely checks whether the call matches the declaration (in case of
function template) and whether the object definition matches class declaration
(in case of class template). Since the function template and the class template
definitions are not found, the compiler leaves it to the linker to restore this.
However, during linking, linker doesn't find the matching definitions for the
function call or a matching definition for object creation. In short the
expanded versions of templates are not found in
the object library. Hence the linker reports error.
-------------------------------------------------------------------------------------------------
36.What is the difference between an inspector and a mutator ?
Ans: An inspector is a member function that returns information about an
object's state (information stored in object's data members) without changing
the object's state. A mutator is a member function that changes the state of an
object. In the class Stack given below we have defined a mutator and an
inspector.
class Stack
{
public :
int pop( ) ;
int getcount( ) ;
}
In the above example, the function pop( ) removes top element of stack thereby
changing the state of an object. So, the function pop( ) is a mutator. The
function getcount( ) is an inspector because it simply counts the number of
elements in the stack without changing the stack.
37. Namespaces:
The C++ language provides a single global namespace. This can cause problems
with global name clashes. For instance, consider these two C++ header files:
// file1.h
float f ( float, int ) ;
class sample { ... } ;
// file2.h
class sample { ... } ;
With these definitions, it is impossible to use both header files in a single
program; the sample classes will clash.A namespace is a declarative region that
attaches an additional identifier to any names declared inside it. The
additional identifier thus avoids the possibility that a name will conflict with
names declared elsewhere in the program. It is possible to use the same name in
separate namespaces without conflict even if the names appear in the same
translation unit. As long as they appear in separate namespaces, each name will
be unique because of the addition of the namespace identifier. For example:
// file1.h
namespace file1
{
float f ( float, int ) ;
class sample { ... } ;
}
// file2.h
namespace file2
{
class sample { ... } ;
}
Now the class names will not clash because they become file1::sample and
file2::sample, respectively.
-------------------------------------------------------------------------------------------------
38.What would be the output of the following program?
#include
class user
{
int i ;
float f ;
char c ;
public :
void displaydata( )
{
cout << endl << i << endl << f << endl << c
;
}
} ;
void main( )
{
cout << sizeof ( user ) ;
user u1 ;
cout << endl << sizeof ( u1 ) ;
u1.displaydata( ) ;
}
Ans: The output of this program would be,
9 or 7
9 or 7
Garbage
Garbage
Garbage
Since the user class contains three elements, int, float and char its size would
be 9 bytes (int-4, float-4, char-1) under Windows and 7 bytes (int-2, float-4,
char-1) under DOS. Second output is again the same because u1 is an object of
the class user. Finally three garbage values are printed out because i, f and c
are not initialized anywhere in the program.
Note that if you run this program you may not get the answer shown here. This is
because packing is done for an object in memory to increase the access
efficiency. For example, under DOS, the object would be aligned on a 2-byte
boundary. As a result, the size of the object would be reported as 6 bytes.
Unlike this, Windows being a 32-bit OS the object would be aligned on a 4-byte
boundary. Hence the size of the object would be reported as 12 bytes. To force
the alignment on a 1-byte boundary, write the following statement before the
class declaration.
#pragma pack ( 1 )
-------------------------------------------------------------------------------------------------
39.Write a program that will convert an integer pointer to an integer and
vice-versa.
Ans: The following program demonstrates this.
#include
void main( )
{
int i = 65000 ;
int *iptr = reinterpret_cast
cout << endl << iptr ;
iptr++ ;
cout << endl << iptr ;
i = reinterpret_cast
cout << endl << i ;
i++ ;
cout << endl << i ;
}
40.What is a
const_cast?
Ans. The const_cast is used to convert a const to a non-const. This is shown in
the following
program:
#include
void main( )
{
const int a = 0 ;
int *ptr = ( int * ) &a ; //one way
ptr = const_cast_
}
Here, the address of the const variable a is assigned to the pointer to a
non-const variable. The const_cast is also used when we want to change the data
members of a class inside the const member functions. The following code snippet
shows this:
class sample
{
private:
int data;
public:
void func( ) const
{
(const_cast
}
} ;