Texas Instrument - Placement Paper - Interview Questions 4

Started by ganeshbala, Mar 14, 2008, 07:17 PM

Previous topic - Next topic

ganeshbala

71. 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
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.

72. 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 << endl ;

73. When friend function becomes indispensable...
Ans: Consider the following program.
#include
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.

74. 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
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

75. 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
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 ;
}

76. 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
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' ) ;
}

77. 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.

78. Can a function call be at the left hand side of the assignment operator?
Ans: Yes. Following program shows how it is possible.
#include
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.

79. 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
class vir
{
public :
virtual void f( )
{
}
} ;
void main( )
{
vir v, v1 ;
int *p1 = ( int* ) &v ;
int *p2 = ( int* ) &v1 ;
cout << endl << *p1 << " " << *p2 ;
}

80. 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
}
}

81. 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.

82. Can you access private data members of a class from out side the class?
Ans: Yes. This program shows how.
#include
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( ).

83. 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.

84. How do I call a virtual function of a class using a pointer to a function ?
Ans :
#include
class Cvirtual
{
public :
virtual float vfun( )
{
cout << "from vfun" << endl ;
return 7.03f ;
}
} ;
void main( )
{
Cvirtual obj ;
int **p = ( int ** ) &obj ;
float ( *pf1 ) ( ) ;
pf1 = ( float ( * ) ( ) ) **p ;
float f = ( *pf1 ) ( ) ;
cout << "return val = " << f << endl ;
}
In the above program class Cvirtual consists of a virtual function vfun(). In variable p we have stored the address of an object of class Cvirtual. While doing so, we have type casted the address of obj to int **, because obj holds a hidden data member called vptr, which in turn holds the address of virtual function vfun( ). In pf1, a pointer to a function, we are collecting the address of the virtual function vfun( ). Thus the value returned by vfun( ) would then get collected in f.

85. Why an overloaded new operator defined in a class is static?
Ans: An overloaded new function is by default static even if it is not declared so. This is because non-static member functions can be called through an object only. But when an overloaded new operator function gets called the object doesn't stand created. Since new operator function itself is responsible for creating the object. Hence to be able to call a function without an object, the function must be static.

86. What is a pure virtual destructor?
Ans: Like a pure virtual function we can also have a pure virtual destructor. If a base class contains a pure virtual destructor it becomes necessary for the derived classes to implement the destructor. An ordinary pure virtual function does not have a body but pure virtual destructor must have a body. This is because all the destructors in the hierarchy of inheritance are always called as a part of destruction.

87. When we are required to find offset of an element within a structure? or, how do we call the function of an outer class from a function in the inner class? (The inner class is nested in the outer class)
Ans:
#include
class outer
{
int i ;
float f ;
public :
class inner
{
public :
infunc( )
{
outer *pout ;
pout = (outer*) this - ( size_t ) &( ( ( outer* ) 0 ) -> in ) ;
pout -> outfunc( ) ;
}
} ;
inner in ;
outfunc( )
{
cout << "in outer class's function" ;
}
} ;
void main( )
{
outer out ;
out.in.infunc( )
}
In the above example we are calling outer::outfunc( ) from inner::infunc(). To call outfunc( ) we need a pointer to the outer class. To get the pointer we have subtracted offset of the inner class's object (base address of outer class's object - address of inner class's object) from address of inner class's object.

88. void f ( float n, int i = 10 ) ;
void f ( float a ) ;
void main( )
{
f ( 12.6 ) ;
}
void f ( float n, int i )
{
}
void f ( float n )
{
}
The above program results in an error (ambiguous call) since without the default argument the two functions have arguments that are matching in number, order and type.

89. Some programs need to exercise precise control over the memory areas where data is placed. For example, suppose we wish to read the contents of the boot sector into a structure. For this the byte arrangement of the structure elements must match the arrangement of various fields in the boot sector of the disk.
The #pragma pack directives offer a way to fulfill this requirement. The #pragma pack directive specifies packing alignment for structure and union members. The #pragma takes effect at the first structure or union declaration after the #pragma is seen. Consider the following structure:
#pragma pack (1)
struct emp
{
int a ;
float s ;
char ch ;
} ;
#pragma pack( )
Here, #pragma pack ( 1 ) lets each structure element to begin on a 1-byte boundary. Hence the size of the structure will be 9. (int - 4, float - 4, char - 1). If we use #pragma pack ( 2 ) each structure element can begin on a 2-byte boundary. Hence the size of the structure will be 10. (int - 4, float - 4, char - 2).

90. How to restrict a friend class's access to the private data members?
Ans: If we declare a class as a friend of our class the friend class can access the private data members of our class. However, if we want we can restrict this access to some selective functions of the class. Following program shows how to achieve this:
#include
class X
{
public :
void print ( class Z &z ) ;
} ;
class Z
{
private :
int i ;
public :
Z ( int ii )
{
i = ii ;
}
friend X::print ( class Z &z ) ;
} ;
void X::print ( Z &z1 )
{
cout << z1.i ;
}
main( )
{
Z z ( 10 ) ;
X x ;
x.print ( 10 ) ;
}
In the above program only the X::print( ) function can access the private data members of class Z.