C++ Interview Questions

What is encapsulation??

Containing and hiding information about an object, such as internal data
structures and code. Encapsulation isolates the internal complexity of an
object’s operation from the rest of the application. For example, a client
component asking for net revenue from a business object need not know the data’s
origin.

What is inheritance?

Inheritance allows one class to reuse the state and behavior of another
class. The derived class inherits the properties and method implementations of
the base class and extends it by overriding methods and adding additional
properties and methods.

What is Polymorphism??

Polymorphism allows a client to treat different objects in the same way even if they were created from different classes and exhibit different behaviors.

You can use implementation inheritance to achieve polymorphism in languages such as C++ and Java.

Base class object’s pointer can invoke methods in derived class objects.

You can also achieve polymorphism in C++ by function overloading and operator
overloading.

What is constructor or ctor?

Constructor creates an object and initializes it. It also creates vtable for
virtual functions. It is different from other methods in a class.

What is destructor?

Destructor usually deletes any extra resources allocated by the object.

What is default constructor?

Constructor with no arguments or all the arguments has default values.

What is copy constructor?

Constructor which initializes the it’s object member variables ( by shallow copying) with another object of the same class. If you don’t implement one in your class then compiler implements one for you.

for example:

  • Boo Obj1(10); // calling Boo constructor
  • Boo Obj2(Obj1); // calling boo copy constructor
  • Boo Obj2 = Obj1;// calling boo copy constructor

When are copy constructors called?

Copy constructors are called in following cases:

  1. when a function returns an object of that class by value
  2. when the object of that class is passed by value as an argument to a function
  3. when you construct an object based on another object of the same class
  4. When compiler generates a temporary object

What is assignment operator?

Default assignment operator handles assigning one object to another of the
same class. Member to member copy (shallow copy)

What are all the implicit member functions of the class? Or what are all the functions which compiler implements for us if we don’t define one.??

  • default ctor
  • copy ctor
  • assignment operator
  • default destructor
  • address operator

What is conversion constructor?

constructor with a single argument makes that constructor as conversion ctor and it can be used for type conversion.

for example:

class Boo {
public:
  Boo( int i );
};
Boo BooObject = 10 ; // assigning int 10 Boo object

What is conversion operator??

class can have a public method for specific data type conversions.

for example:

class Boo {
 double value;
public:
 Boo(int i )
 operator double() {
  return value;
 }
};
Boo BooObject;
double i  = BooObject; // assigning object to variable i of type double.
now conversion  operator gets called to assign the value.

What is diff between malloc()/free() and new/delete?

malloc allocates memory for object in heap but doesn’t invoke object’s constructor to initiallize the object.

new allocates memory and also invokes constructor to initialize the object.

malloc() and free() do not support object semantics

Does not construct and destruct objects

string * ptr = (string *)(malloc (sizeof(string)))

Are not safe

Does not calculate the size of the objects that it construct

Returns a pointer to void

int *p = (int *) (malloc(sizeof(int)));

int *p = new int;

Are not extensible

new and delete can be overloaded in a class

“delete” first calls the object’s termination routine (i.e. its destructor) and then releases the space the object occupied on the heap memory. If an array of objects was created using new, then delete must be told that it is dealing with an array by preceding the name with an empty []:-

Int_t *my_ints = new Int_t[10];

delete []my_ints;

what is the diff between “new” and “operator new” ?

“operator new” works like malloc.

What is difference between template and macro??

There is no way for the compiler to verify that the macro parameters are of compatible types. The macro is expanded without any special type checking.

If macro parameter has a postincremented variable ( like c++ ), the increment is performed two times.

Because macros are expanded by the preprocessor, compiler error messages will refer to the expanded macro, rather than the macro definition itself. Also, the macro will show up in expanded form during debugging.

for example:

Macro:

#define min(i, j) (i < j ? i : j)

template:

template<class T>
T min (T i, T j) {
 return i < j ? i : j;
}

What are C++ storage classes?

  • auto
  • register
  • static
  • extern

auto: the default. Variables are automatically created and initialized when they are defined and are destroyed at the end of the block containing their definition. They are not visible outside that block

register: a type of auto variable. a suggestion to the compiler to use a CPU register for performance

static: a variable that is known only in the function that contains its definition but is never destroyed and retains its value between calls to that function. It exists from the time the program begins execution

extern: a static variable whose definition and placement is
determined when all object and library modules are combined (linked) to form the
executable code file. It can be visible outside the file where it is defined.

What are storage qualifiers in C++ ?

  • const
  • volatile
  • mutable

Const keyword indicates that memory once initialized, should not be altered by a program.

volatile keyword indicates that the value in the memory location can
be altered even though nothing in the program

code modifies the contents. for example if you have a pointer to hardware
location that contains the time, where hardware changes the value of this
pointer variable and not the program. The intent of this keyword to improve the
optimization ability of the compiler.

mutable keyword indicates that particular member of a structure or class can be altered even if a particular structure variable, class, or class member function is constant.

struct data {
 char name[80];
 mutable double salary;
}
const data MyStruct = { "Satish Shetty", 1000 }; //initlized by complier
strcpy ( MyStruct.name, "Shilpa Shetty"); // compiler error
MyStruct.salaray = 2000 ; // complier is happy allowed

What is reference ??

reference is a name that acts as an alias, or alternative name, for a previously defined variable or an object.

prepending variable with “&” symbol makes it as reference.

for example:
int a;
int &b = a;

What is passing by reference?

Method of passing arguments to a function which takes parameter of type reference.

for example:

void swap( int & x, int & y ) {
 int temp = x;
 x = y;
 y = temp;
}
int a=2, b=3;
swap( a, b );

Basically, inside the function there won’t be any copy of the arguments
“x” and “y” instead they refer to original variables a and
b. so no extra memory needed to pass arguments and it is more efficient.

When do use “const” reference arguments in function?

a) Using const protects you against programming errors that inadvertently
alter data.

b) Using const allows function to process both const and non-const actual
arguments, while a function without const in the prototype can only accept non
constant arguments.

c) Using a const reference allows the function to generate and use a temporary
variable appropriately.

When are temporary variables created by C++ compiler?

Provided that function parameter is a “const reference”, compiler generates temporary variable in following 2 ways.

a) The actual argument is the correct type, but it isn’t Lvalue

double Cube(const double & num) {
 num = num * num * num;
 return num;
}
double temp = 2.0;
double value = cube(3.0 + temp); // argument is a expression and not a Lvalue;

b) The actual argument is of the wrong type, but of a type that can be converted to the correct type

long temp = 3L;
double value = cuberoot ( temp); // long to double conversion

What is virtual function?

When derived class overrides the base class method by redefining the same function, then if client wants to access redefined the method from derived class through a pointer from base class object, then you must define this function in base class as virtual function.

class parent {
 void Show() {
  cout << "i'm parent" << endl;
 }
};

class child: public parent {
 void Show() {
  cout << "i'm child" << endl;
 }
};

parent * parent_object_ptr = new child;
parent_object_ptr->show() // calls parent->show() i

now we goto virtual world...

class parent {
 virtual void Show() {
  cout << "i'm parent" << endl;
 }
};

class child: public parent {
 void Show() {
  cout << "i'm child" << endl;
 }
};

parent * parent_object_ptr = new child;
parent_object_ptr->show() // calls child->show()

What is pure virtual function? or what is abstract class?

When you define only function prototype in a base class without implementation and do the complete implementation in derived class. This base class is called abstract class and client won’t able to instantiate an object using this base class.

You can make a pure virtual function or abstract class this way..

class Boo {
 void foo() = 0;
}
Boo MyBoo; // compilation error

What is Memory alignment??

The term alignment primarily means the tendency of an address pointer value
to be a multiple of some power of two. So a pointer with two byte alignment has
a zero in the least significant bit. And a pointer with four byte alignment has
a zero in both the two least significant bits. And so on. More alignment means a
longer sequence of zero bits in the lowest bits of a pointer.

What problem does the namespace feature solve?

Multiple providers of libraries might use common global identifiers causing a name collision when an application tries to link with two or more such libraries. The namespace feature surrounds a library’s external declarations with a unique namespace that eliminates the potential for those collisions.

namespace [identifier] { namespace-body }

A namespace declaration identifies and assigns a name to a declarative
region.

The identifier in a namespace declaration must be unique in the declarative
region in which it is used. The identifier is the name of the namespace and is
used to reference its members.

What is the use of ‘using’ declaration?

A using declaration makes it possible to use a name from a namespace without
the scope operator.

What is an Iterator class?

A class that is used to traverse through the objects maintained by a
container class. There are five categories of iterators: input iterators, output
iterators, forward iterators, bidirectional iterators, random access. An
iterator is an entity that gives access to the contents of a container object
without violating encapsulation constraints. Access to the contents is granted
on a one-at-a-time basis in order. The order can be storage order (as in lists
and queues) or some arbitrary order (as in array indices) or according to some
ordering relation (as in an ordered binary tree). The iterator is a construct,
which provides an interface that, when called, yields either the next element in
the container, or some value denoting the fact that there are no more elements
to examine. Iterators hide the details of access to and update of the elements
of a container class. Something like a pointer.

What is a dangling pointer?

A dangling pointer arises when you use the address of an object after its
lifetime is over. This may occur in situations like returning addresses of the
automatic variables from a function or using the address of the memory block
after it is freed.

What do you mean by Stack unwinding?

It is a process during exception handling when the destructor is called for
all local objects in the stack between the place where the exception was thrown
and where it is caught.

Name the operators that cannot be overloaded??

sizeof,  .,   .*,   .->,   ::,   ?:

What is a container class? What are the types of container classes?

A container class is a class that is used to hold objects in memory or
external storage. A container class acts as a generic holder. A container class
has a predefined behavior and a well-known interface. A container class is a
supporting class whose purpose is to hide the topology used for maintaining the
list of objects in memory. When a container class contains a group of mixed
objects, the container is called a heterogeneous container; when the container
is holding a group of objects that are all the same, the container is called a
homogeneous container.

What is inline function??

The __inline keyword tells the compiler to substitute the code within the
function definition for every instance of a function call. However, substitution
occurs only at the compiler’s discretion. For example, the compiler does not
inline a function if its address is taken or if it is too large to inline.

What is overloading??

With the C++ language, you can overload functions and operators. Overloading is the practice of supplying more than one definition for a given function name in the same scope.

  • Any two functions in a set of overloaded functions must have different argument lists.
  • Overloading functions with argument lists of the same types, based on return type alone, is an error.

What is Overriding?

To override a method, a subclass of the class that originally declared the
method must declare a method with the same name, return type (or a subclass of
that return type), and same parameter list.

The definition of the method overriding is:

  • Must have same method name.
  • Must have same data type.
  • Must have same argument list.

Overriding a method means that replacing a method functionality in child class.
To imply overriding functionality we need parent and child classes. In the child
class you define the same method signature as one defined in the parent class.

What is “this” pointer?

The this pointer is a pointer accessible only within the member functions of a class, struct, or union type. It points to the object for which the member function is called. Static member functions do not have a this pointer.

When a nonstatic member function is called for an object, the address of the object is passed as a hidden argument to the function. For example, the following function call

myDate.setMonth( 3 );

can be interpreted this way:

setMonth( &myDate, 3 );

The object’s address is available from within the member function as the this
pointer. It is legal, though unnecessary, to use the this pointer when referring
to members of the class.

What happens when you make call “delete this;” ??

The code has two built-in pitfalls. First, if it executes in a member function for an extern, static, or automatic object, the program will probably crash as soon as the delete statement executes. There is no portable way for an object to tell that it was instantiated on the heap, so the class cannot assert that its object is properly instantiated. Second, when an object commits suicide this way, the using program might not know about its demise. As far as the instantiating program is concerned, the object remains in scope and continues to exist even though the object did itself in. Subsequent dereferencing of the pointer can and usually does lead to disaster.

You should never do this. Since compiler does not know whether the object was
allocated on the stack or on the heap, “delete this” could cause a
disaster.

How virtual functions are implemented C++?

Virtual functions are implemented using a table of function pointers, called
the vtable.  There is one entry in the table per virtual function in the
class.  This table is created by the constructor of the class.  When a
derived class is constructed, its base class is constructed first which creates
the vtable.  If the derived class overrides any of the base classes virtual
functions, those entries in the vtable are overwritten by the derived class
constructor.  This is why you should never call virtual functions from a
constructor: because the vtable entries for the object may not have been set up
by the derived class constructor yet, so you might end up calling base class
implementations of those virtual functions

What is name mangling in C++??

The process of encoding the parameter types with the function/method name into a unique name is called name mangling. The inverse process is called demangling.

For example Foo::bar(int, long) const is mangled as `bar__C3Fooil’.

For a constructor, the method name is left out. That is Foo::Foo(int, long)
const is mangled as `__C3Fooil’.

What is the difference between a pointer and a reference?

A reference must always refer to some object and, therefore, must always be initialized; pointers do not have such restrictions. A pointer can be reassigned to point to different objects while a reference always refers to an object with which it was initialized.

How are prefix and postfix versions of operator++() differentiated?

The postfix version of operator++() has a dummy parameter of type int. The prefix version does not have dummy parameter.

What is the difference between const char *myPointer and char *const myPointer?

Const char *myPointer is a non constant pointer to constant data; while char *const myPointer is a constant pointer to non constant data.

How can I handle a constructor that fails?

throw an exception. Constructors don’t have a return type, so it’s not possible to use return codes. The best way to signal constructor failure is therefore to throw an exception.

How can I handle a destructor that fails?

Write a message to a log-file. But do not throw an exception.

The C++ rule is that you must never throw an exception from a destructor that is
being called during the “stack unwinding” process of another
exception. For example, if someone says throw Foo(), the stack will be unwound
so all the stack frames between the throw Foo() and the } catch (Foo e) { will
get popped. This is called stack unwinding.

During stack unwinding, all the local objects in all those stack frames are
destructed. If one of those destructors throws an exception (say it throws a Bar
object), the C++ runtime system is in a no-win situation: should it ignore the
Bar and end up in the } catch (Foo e) { where it was originally headed? Should
it ignore the Foo and look for a } catch (Bar e) { handler? There is no good
answer — either choice loses information.

So the C++ language guarantees that it will call terminate() at this point, and
terminate() kills the process. Bang you’re dead.

What is Virtual Destructor?

Using virtual destructors, you can destroy objects without knowing their type – the correct destructor for the object is invoked using the virtual function mechanism. Note that destructors can also be declared as pure virtual functions for abstract classes.

if someone will derive from your class, and if someone will say “new
Derived”, where “Derived” is derived from your class, and if
someone will say delete p, where the actual object’s type is “Derived”
but the pointer p’s type is your class.

Can you think of a situation where your program would crash without reaching the breakpoint which you set at the beginning of main()?

C++ allows for dynamic initialization of global variables before main() is
invoked. It is possible that initialization of global will invoke some function.
If this function crashes the crash will occur before main() is entered.

Name two cases where you MUST use initialization list as opposed to assignment in constructors.

Both non-static const data members and reference data members cannot be
assigned values; instead, you should use initialization list to initialize
them.

Can you overload a function based only on whether a parameter is a value or a reference?

No. Passing by value and by reference looks identical to the caller.

What are the differences between a C++ struct and C++ class?

The default member and base class access specifiers are different.

The C++ struct has all the features of the class. The only differences are
that a struct defaults to public member access and public base class
inheritance, and a class defaults to the private access specifier and private
base class inheritance.

What does extern “C” int func(int *, Foo) accomplish?

It will turn off “name mangling” for func so that one can link to
code compiled by a C compiler.

How do you access the static member of a class?

<ClassName>::<StaticMemberName>

What is multiple inheritance(virtual inheritance)? What are its advantages and disadvantages?

Multiple Inheritance is the process whereby a child can be derived from more than one parent class. The advantage of multiple inheritance is that it allows a class to inherit the functionality of more than one base class thus allowing for modeling of complex relationships. The disadvantage of multiple inheritance is that it can lead to a lot of confusion(ambiguity) when two base classes implement a method with the same name.

What are the access privileges in C++? What is the default access level?

The access privileges in C++ are private, public and protected. The default
access level assigned to members of a class is private. Private members of a
class are accessible only within the class and by friends of the class.
Protected members are accessible by the class itself and it’s sub-classes.
Public members of a class can be accessed by anyone.

What is a nested class? Why can it be useful?

A nested class is a class enclosed within the scope of another class. For example:

//  Example 1: Nested class
//
class OuterClass {
 class NestedClass {
  // ...
 };
 // ...
};

Nested classes are useful for organizing code and controlling access and
dependencies. Nested classes obey access rules just like other parts of a class
do; so, in Example 1, if NestedClass is public then any code can name it as
OuterClass::NestedClass. Often nested classes contain private implementation
details, and are therefore made private; in Example 1, if NestedClass is
private, then only OuterClass’s members and friends can use NestedClass.

When you instantiate as outer class, it won’t instantiate inside class.

What is a local class? Why can it be useful?

local class is a class defined within the scope of a function — any function, whether a member function or a free function. For example:

//  Example 2: Local class
//
int f() {
 class LocalClass {
  // ...
 };
 // ...
};

Like nested classes, local classes can be a useful tool for managing code
dependencies.

Can a copy constructor accept an object of the same class
as parameter, instead of reference of the object?

No. It is specified in the definition of the copy constructor itself. It
should generate an error if a programmer specifies a copy constructor with a
first argument that is an object and not a reference.

An array is instantiated with the new[] operator. Is it sufficient to delete the array using a delete operator or should a delete[] operator be used? Justify your answer.

The delete[] operator should always be used. This restriction applies for both built-in types (char, int and others) and for aggregate types (structs and classes). This is required by the C++ language definition (the Annotated C++ Reference Manual).

Can I drop the [] when deleting an array of some built-in type (char, int, etc)?

No. Marshall Cline’s C++ FAQ Lite contains a good explanation at parashift.com

What is an example of when a destructor is NOT called at the end of scope?

Bjarne Stroustrup’s C++ Style and Technique FAQ provides an excellent explanation at att.com. The short answer is that objects that are created on the heap are not automatically destroyed at the end of the scope that created the object.

In addition to Bjarne Stroustrup’s answer, I would also add that statically created objects are also not destroyed at the end of the scope.

Explain stack unwinding.

Stack unwinding occurs when an exception is thrown and control passes from a try block to a handler. Automatic objects are destroyed in the reverse order of their construction. If a destructor throws an exception during the stack unwinding process, terminate is called.

From the Borland C++ Builder help:

When an exception is thrown, the runtime library takes the thrown object, gets the type of the object, and looks upward in the call stack for a handler whose type matches the type of the thrown object. Once a handler is found, the RTL unwinds the stack to the point of the handler, and executes the handler. In the unwind process, the RTL calls destructors for all local objects in the stack frames between where the exception was thrown and where it is caught. If a destructor causes an exception to be raised during stack unwinding and does not handle it, terminate is called. Destructors are called by default, but you can switch off the default by using the -xd compiler option.

Objects that are not allocated on the stack, such as heap allocations, are not automatically released. This can cause memory leaks unless the programmer takes extra precautions to release the allocated memory when an exception is thrown. There are various ways to prevent heap-memory leaks caused by stack unwinding. One way is a user-defined garbage-collection; a second way is to specifically deallocate those resources in the exception handler.

When I write a derived class’s destructor, do I need to explicitly call the destructor for my base class?

Marshall Cline’s C++ FAQ Lite answers this question with “No”. A more explicit explanation with an example is at parashift.com.

Explain the difference between a class and an object.

A class is a blueprint for an object. It defines how the object will be created, what data is stored, how the data can be manipulated and how the object will be destroyed. An object is an instantiation of a class. There can be multiple objects instantiated from one class. Every object has one and only one class that it was instantiated from.

Explain the difference between a struct and a class.

The default members and base classes of a class are private. The default members and base classes of a struct are public.

Other than the default protection, struct and class are equivalent.

An unwritten practice amongst C++ programmers is to define a class for objects that have few or no public data members and to define a struct for objects that have few or no public methods.

What is difference between malloc/free and new/delete?

malloc() and new both allocate space from the heap. free() and delete both release previously allocated heap space. free() should only be used with malloc’d allocations and delete should only be used with new allocations. There are two varieties of new: array allocation through a new[] operator and single object allocation through a new operator. It’s the programmer’s responsibility to know and track which allocation method was used in order to apply the correct deallocation: free(), delete or array delete (operator delete[]).

Polymorphism

is the ability of a pointer to a derived object to be type-compatible with a pointer to its base class. If the interviewer’s follow-up question is, “Huh?”, you can answer:

Polymorphism allows two or more classes derived from the same base class to share a common base member function but have different behaviors. Moving to a whiteboard, you can whip up the sample program in Listing A. It uses a pure virtual base member but that’s not a requirement. A regular virtual base member would also have been acceptable.

#include <iostream>

using namespace std;

class Vehicle {
public:
  virtual string getFuel() = 0;
};

class Car : public Vehicle {
public:
  virtual string getFuel()
    { return "gasoline"; }
};

class Truck : public Vehicle {
public:
  virtual string getFuel()
    { return "diesel"; }
};

void printFuel(Vehicle &v) {
  cout << v.getFuel() << endl;
}

int main(int, char **) {
  Car car;
  Truck truck;
  printFuel(car);
  printFuel(truck);
  return 0;
}
Listing A: Example of Polymorphism

In Listing A, polymorphism occurs with the Vehicle parameter for the printFuel() function. printFuel() can accept either an instantiation of Car or an instantiation of Truck.

A follow-up question might ask if a Vehicle object could be passed to the printFuel() function. The answer is “no” because Vehicle uses a pure-virtual function and classes with pure-virtual functions can not be instantiated.

virtual

is a C++ keyword that is used for virtual methods and for virtual base classes.

mutable

is a storage-class specifier. It allows const-member functions to modify the data member.

explicit

is used on constructors that have one parameter. It prevents automatic type conversion from changing a candidate parameter into the type used in the constructor.

template

metaprogramming is an idiom that uses templates to generate source code that calculates an answer at compile-time rather than at run-time.

Follow-up questions would ask about the Curiously Recurring Template Pattern, the Barton-Nackman trick, static polymorphism in template metaprogramming and the benefits and drawbacks of template metaprogramming. See wikipedia.org for a good explanation along with cross reference material.

public, private and protected

are the access control specifiers in class and struct designs. All three of the keywords are used to control the access to methods and data in base classes and in derived classes. Listing A shows an example of a Car class defining public access to a Vehicle class. The Vehicle class defines public access of the getFuel() pure virtual method.

The static

keyword is used all over the place in the C++ language. When used inside of a method or function, the static keyword preserves the last value of a variable between method or function calls. Inside of a class definition, a data value can be declared static — this causes one version of the data to be shared amongst all of the objects of the class. Static member functions can not be virtual because they have external linkage. External linkage means that the function does not have a this pointer and the function can only call other static member functions and access static data.

An assignment operator

is a simple equal (=) sign for built-in types or the operator=() method for objects. If your first answer only provided one of those assignment operators, a good interviewer would ask something like “is that all?”. Written tests can’t do that, of course, so be careful when giving what seems like an obvious answer.

A dangling pointer

can be an unassigned pointer or it can be a pointer to an object that has been destroyed.

A functor

is short for function object. Function objects are used as callbacks to modify or customize the behavior of an algorithm. Function objects define a member function that provides the glue between an algorithm and the customized behavior. Because functors are full-fledged objects, they have all of the power of an object: state, inheritance, encapsulation and templates. In Listing B, the operator() method of the magnitude structure is a functor. Listing C takes a slightly different approach by using an arbitrary method name, in this case called “isGreaterThan”, to attach a customized behavior to an algorithm.

#include <algorithm>
#include <function>
#include <assert>
#include <iostream>

using namespace std;

// Use the absolute value (magnitude) of the
// number.  For example:  3 < -5 because abs(3) < abs(-5)
struct magnitude {
  bool operator()(const int& x, const int& y)
    const
    { return abs(x) < abs(y); }
};

int main(int, char **) {
  int a[10];
  int i;

  for(i = 0; i < 10; ++i)
    a[i] = i * (i % 2 ? -1 : 1);
  random_shuffle(&a[0], &a[10]);

  // sort into special order:
  sort(&a[0], &a[10], magnitude());

  // Should be: 0,-1,2,-3,4,-5,6,-7,8,-9,
  for(i = 0; i < 10; ++i)
    cout << a[i] << ",";
  cout << endl;

  return 0;
}
Listing B: Functor Example

#include <algorithm>
#include <iostream>

using namespace std;

// Used to allow for generic implementations of bubble_sort
struct SortOrder {
  virtual bool isGreaterThan(const int x, const int y) const = 0;
};

void bubble_sort(int *first, int *last, SortOrder &compare) {
  int numLaps = last - first - 1;
  for(int lap = 0; lap < numLaps; ++lap) {
    for(int *current = first; current != last; ++current) {
      int *next = current + 1;
      if (next == last)
        continue;
      if (compare.isGreaterThan(*current, *next)) {
        std::swap(*current, *next);
      }
    }
  }
}

// Use the absolute value (magnitude) of the
// number.  For example:  3 < -5 because abs(3) < abs(-5)
struct Magnitude : SortOrder {
  virtual bool isGreaterThan(const int x, const int y) const
    { return abs(x) > abs(y); }
};

int main(int, char **) {
  int a[10];
  int i;

  for(i = 0; i < 10; ++i)
    a[i] = i * (i % 2 ? -1 : 1);
  random_shuffle(&a[0], &a[10]);

  // sort into special order:
  Magnitude sort_by_magnitude;
  bubble_sort(&a[0], &a[10], sort_by_magnitude);

  // Should be: 0,-1,2,-3,4,-5,6,-7,8,-9,
  for(i = 0; i < 10; ++i)
    cout << a[i] << ",";
  cout << endl;

  return 0;
}
Listing C: Another Functor Example

STL

Standard Template Library

RAII

Resource Allocation is Initialization. See http://www.hackcraft.net/raii/ for a well-written tutorial on RAII.

VCL

Visual Component Library. I’ll admit that even though I knew what the VCL was, I didn’t know what its acronym stood for until I wrote this article.

C++

Quote from Chapter 1 of the C++ Programming Language (Stroustrup)

“The name C++ … was coined by Rick Mascitti in the summer of 1983. The name signifies the evolutionary nature of the changes from C; “++” is the C increment operator.”

See also att.com.

A WChar

type in a program you didn’t write would typically be a wide (16-bit) character type.

What executes faster: ++i or i++, where i is an integer variable?

++i probably executes faster because i++ would first fetch the value of i, push it on the stack, increment it and then pop the value of i from the stack. In contrast, ++i fetches the value of i, and then increments it. Yes, I’m leaving a lot of detail out and the push/pop cycle can be optimized away for many situations if the optimizer is good enough.

Which is generally more efficient: a function that returns a reference or a function that does not return a reference?

Functions that don’t return a reference are returning the object by value. This is accomplished by using the object’s copy constructor. For non-trivial objects, the time and resource cost of copying the object can be easily measured. Functions that return an object by reference only return a pointer to the object. The object the reference points to is not copied.

What’s the deal with inline functions?

The keyword inline is a hint to the compiler that the function should be compiled into the code wherever it is used. This is normally done with a simple function that is called often, such as a getter or setter in a class or struct. The compiler implementer is allowed to ignore the inline hint and substitute a function call instead. Some compilers automatically disable the inlining of functions while debugging.

Why use the STL sort() when we have “good old qsort()”?

The following answer is quoted from public.research.att.com:

To a novice,
qsort(array,asize,sizeof(elem),compare);
looks pretty weird, and is harder to understand than
sort(vec.begin(),vec.end());
To an expert, the fact that sort() tends to be faster than qsort() for the same elements and the same comparison criteria is often significant. Also, sort() is generic, so that it can be used for any reasonable combination of container type, element type, and comparison criterion. For example:

struct Record {
  string name;
  // ...
};

struct name_compare {	// compare Records using "name" as the key
  bool operator()(const Record& a, const Record& b) const
    { return a.name<b.name; }
};

void f(vector<Record>& vs)
{
  sort(vs.begin(), vs.end(), name_compare());
  // ...
}

In addition, most people appreciate that sort() is type safe, that no casts are required to use it, and that they don’t have to write a compare() function for standard types. The primary reason that sort() tends to outperform qsort() is that the comparison inlines better.

One programmer wants to sort a linked list using recursion; another programmer wants to do it without recursion. Which one has the better answer?

It depends on the maximum number of items in the linked list. An implementation that uses recursion will eventually run out of stack space if the linked list is long enough. If the number of items in the linked list is relatively small, say around 30 or so, then either solution might be faster but both implementations will be so fast that it’s usually not worth optimizing that one little routine. If the number of items in the list could ever be more than 30, then a non-recursive solution would probably be better because it will not run out of stack space when compared with the recursive solution.

When is an interface “good”?

From parashift.com:

When it provides a simplified view of a chunk of software, and it is expressed in the vocabulary of a user (where a “chunk” is normally a class or a tight group of classes, and a “user” is another developer rather than the ultimate customer). The “simplified view” means unnecessary details are intentionally hidden. This reduces the user’s defect-rate. The “vocabulary of users” means users don’t need to learn a new set of words and concepts. This reduces the user’s learning curve.

What language feature is available when a function returns a reference?

The C++ FAQ-lite at parashift.com answers this question:

The function call can appear on the left hand side of an assignment operator. This ability may seem strange at first. For example, no one thinks the expression f() = 7 makes sense. Yet, if a is an object of class Array, most people think that a[i] = 7 makes sense even though a[i] is really just a function call in disguise (it calls Array::operator[](int), which is the subscript operator for class Array).

class Array {
public:
  int size() const;
  float& operator[] (int index);
  ...
};

int main() {
  Array a;
  for (int i = 0; i < a.size(); ++i)
    a[i] = 7; // invoke Array::operator[](int)
  ...
}

What is name mangling in C++?

Name mangling encodes the type of the function’s parameters into the name in order to create a unique name that is distinguished from identical function names with different parameter types. For example, the parameter int *p might be mangled to “intPtr”. A function prototype defined as:

doit(int *p);

could name mangle the doit function into doit_intPtr.

Name mangling is compiler specific. The primary reason why object libraries from one compiler can not be linked with object libraries from another compiler is because each compiler vendor uses a slightly different name mangling scheme.

What is overriding?

Overriding only occurs in a class hierarchy. An overridden method is one that is hidden from the normal method call hierarchy by a derived class that has a method with the same name, return type and parameter list. When a method is overridden by a subclass’s method, the subclass’s method is called instead of the parent class’s method.

Can you assign to a reference?

Yes, you can. Here’s an example:

int i;
int &j = i;
j = 5;   // changes i to 5

What happens if you assign to a reference?

From parasoft.com:

You change the state of the referent (the referent is the object to which the reference refers). Remember: the reference is the referent, so changing the reference changes the state of the referent. In compiler writer lingo, a reference is an “lvalue” (something that can appear on the left hand side of an assignment operator).

What is a static_cast and when should it be used?

static_cast<> is the general replacement for the old-style (cast). A static_cast<> is safer than a (cast) because static_cast<> verifies at compile-time that the conversion makes sense.

What are the names of the other cast operators?

const_cast, reinterpret_cast and dynamic_cast.

How do you trap an exception without knowing what exception might be thrown?

Use the … wildcard in the exception handler.

Describe how you design a program.

Any reasonable answer that you can justify will work for this question. The better answers will include the phrases “top-down”, and “bottom-up”. Other phrases that could be used are “divide and conquer”, “requirements gathering”, budgeting, planning, and testing.

A poor answer is along the lines of, “I just sit down and start coding because I get something done right away”. Most employers want to know that you spend time designing the program, that you sit at a blank piece of paper or a whiteboard and sketch out even a rough skeleton of how the program will work.

Programmers that design programs using extensive unit testing get extra credit points. If you’re an advocate of extreme programming (XP) (www.extremeprogramming.org/), this would be a good time to talk about your experiences with XP and how it makes you a more efficient and better software engineer.

Most programming projects involve modifying existing code. What things do you look for when you’re tasked with modifying an existing program?

The first thing I do when I take over a legacy project is to attempt to compile the project in an isolated environment. I record the compile-time warnings I receive and I pay particular attention to any modules that compile with errors because that’s an indication that I have an incomplete or inaccurate development environment. Next, I make a binary comparison between the legacy executable and the newly compiled executable. My goal is to create an executable that is identical to the legacy executable — at that point I know I have the same environment and settings that the previous developers used.

The next thing I usually look at is any existing documentation. Although many C and C++ programming projects are notorious for having little or no documentation (or even inaccurate documentation!), I have seen projects that had extensive, amazing and accurate documentation — even to the point where the number of lines of useful comments exceeded the number of lines of code.

There is a memory leak in a program. What tools and techniques would you use to isolate, find and fix it?

I would first determine how big the memory leak is and look for patterns of when it appears and how quickly it grows. If the memory leak is small or grows slowly and the program terminates soon anyway, then I would say that the problem isn’t worth fixing. This isn’t out of laziness — it’s a prudent decision that recognizes that some things are too expensive to fix.

If a leak was determined to be worthy of fixing, I would next look for the smallest set of code that reproduces the problem. Can the problem be reproduced by launching and then immediately exiting the program? What’s the simplest thing I can do that causes the biggest memory leak quickly?

I would also realize that there may be multiple memory leaks in the program and they might be interacting with each other in strange ways. An example would be a hash table that leaks whenever the hash table’s contents are rehashed.

On a Windows system, the primary tool I use to monitor memory usage is the Windows Task Manager. A more aggressive approach is to instrument the malloc/free and new/delete methods to provide a log of memory consumption and releases.

Commercial tools are also available to assist in the detection and eradication of memory leaks. If you’ve used one before that you’ve liked, mention it in the interview to earn extra points.

What’s the difference between a linked list and an array?

An array allows random access to the array’s elements. A linked list’s elements can accessed by dereferencing the head (or tail) pointer and then dereferencing the next (or previous) pointers.

Inserting an element into an array is more difficult than inserting an element into a list. Deleting is similarly more difficult in an array than in a list.

Data is stored sequentially in an array but that is not a requirement for a list. Lists’ data can be stored either sequentially or randomly.

What is the difference between a vector, a list and a map?

All three of them are containers in the STL.

Maps use key/value pairs for the elements. The keys are sorted within the map to allow quick random access. Insertion and deletion are both very quick. Access to any particular element is also quick but each element requires a unique key.

STL vectors and STL lists behave the same as arrays and lists (see Q12).

Demeter’s Law

In C++, the Law of Demeter is a guideline for developing class hierarchies. The guideline states that a method inside of an object should only call the methods of:

  1. The object itself
  2. The objects passed as parameters to the method
  3. Objects instantiated within the method
  4. Objects that exist due to has-a relationships within the object

The purpose of the Law of Demeter is to reduce the dependencies between classes. Obeying the law requires the coder to create many wrapper methods that separate callees from callers.

Liskov Substitution Principle

The Liskov Substitution Principle guarantees that code using a pointer to a base class doesn’t break when a new class is added to the class hierarchy. One main principle provide this guarantee: the methods for subclasses are substitutable for the methods in the superclasses for instantiated objects.

Violating the principle requires subclasses (or modified superclasses) to check the object’s state or the type of the subclass to determine how to dereference a request. Most commonly, this manifests itself in code with switch or if statements similar to:

switch (param.type) {
  case Integer:
    retval = param.toInt();
    break;
  case Double:
    retval = param.toDouble();
...

Dependency Inversion

Dependency Inversion abstracts dependencies into subclasses so that the superclasses become so generic that they no longer have interdependencies.

See Robert Martin’s article for more details.

Visitor Pattern

The Visitor Pattern separates an algorithm from an object’s structure. It can perform an operation (or groups of operations) on objects that belong to a structure. The objects are not required to have the same interfaces.

Gang of Four

The Gang of Four are Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides. They collectively became famous for their seminal book “Design patterns : elements of reusable object-oriented software”, Addison-Wesley (ISBN 0201633612 — no, I don’t expect you to memorize the ISBN number — I’m providing it here in case you want to get the book).

Bridge Pattern

A Bridge Pattern separates an abstraction from its implementation so that they can change independently. Some examples of when a Bridge Pattern can be used are:

  1. A reference counting mechanism that is invisible to the clients being counted.
  2. When changes to a class hierarchy cause an exponential increase in the number of subclasses or superclasses.
  3. When interfacing with a legacy system that can not be touched but must be extended.

Find the size of an integer data type without using sizeof() function.

Listing D is an example of one solution. What is not mentioned in the question is if the integer data type is signed or unsigned. Does your solution work for both? For edge-case support, we can assume that the integer data type has at least one bit because a 0-bit integer data type is pretty useless. Does your solution work for 1 or 2 bit integers, or did you assume that integers were a multiple of 8 bits?

#include <stdio.h>

template< typename IntType >
int numberOfBits() {
  IntType newValue = 1;
  IntType oldValue = 0;
  int numBits = 0;
  while(oldValue != newValue) {
    ++numBits;
    oldValue = newValue;
    newValue = (newValue << 1) + 1;
  }
  return numBits;
}

int main(int argc, char* argv[]) {
  printf("sizeof(int)  : %d\n", sizeof(int) * 8);
  printf("size of <int>: %d\n", numberOfBits<int>());
  printf("\n");
  printf("sizeof(unsigned int)  : %d\n", sizeof(unsigned int) * 8);
  printf("size of <unsigned int>: %d\n", numberOfBits<unsigned int>());
  printf("\n");
  printf("sizeof(short)  : %d\n", sizeof(short) * 8);
  printf("size of <short>: %d\n", numberOfBits<short>());
  return 0;
}
Listing D: Detect the size of an integer
Update: March 20, 2011
A decompile.com reader, Ján Staník, has submitted the following alternate solution. The solution in Listing D did not assume there are 8 bits per byte but Ján’s solution does assume there are 8 bits per byte. However, Ján’s solution provides an O(1) solution whereas the solution in Listing D is an O(n) solution.I think it’s useful to examine why his solution works because it makes a clever use of arrays and it calculates the distance between array elements in a template function.The only change I made to his solution was to format it to stay within the minimum page width of this website.

#include <iostream>

template <typename T>
void SizeOf()
{
  T a[2];
  std::cout << "sizeof() = " << 8 * sizeof(T) << std::endl;
  std::cout << "SizeOf<> = ";
  std::cout << 8 * (((long int)((T*)a+1)) - ((long int)(T*)a));
  std::cout << std::endl;
}

int main( )
{
  SizeOf<unsigned int>();
}

Multiply an integer by 8 without using multiplication or addition.

The key to the answer to this question is knowing about the shift operator and how it relates to the integer’s internal representation. The following code snippet answers this question:

int x = 3;
x = x << 3;

What’s wrong with this code?

The problem with the Gimpel Software Bug of the Month #750 (repeated in Listing 1 for your convenience) is on line 11. Carefully look at the ON_THE_R0CKS symbol. The O of ROCKS is actually a zero (0). Gimpel’s PC-lint tool provides a hint to the problem by reporting that the ON_THE_ROCKS symbol is not used in the program even though it’s defined.

1    #include <stdio.h>
2
3    #define ON_THE_ROCKS
4
5    const char *ice()
6    {
7    #if defined(Shaken)
8        return "shaken not stirred";
9    #elif defined(Stirred)
10       return "stirred not shaken";
11   #elif defined(ON_THE_R0CKS)
12       return "on the rocks";
13   #else
14       return "";
15   #endif
16   }
17
18   int main()
19   {
20       printf( "Celebrate the New Year " );
21       printf( "with your drink %s.\n", ice() );
22       return 0;
23   }
Listing 1: Gimpel Softare Bug Example

The zero in the ON_THE_R0CKS symbol causes the ice() function to compile with one line:

return "";

Many thanks to alert reader ZenJu for correcting my original answer.

The next code sample is actually in C#. You might think that it’s not fair to use a C# code sample in a C++ interview. I, as an interviewer, would not do that but I’ve been in an interview where the interviewer thought that JavaScript and Java were the same thing. If you recognized that the program was in C# and said something to the interviewer in a cordial way, then points for you. Even though you might not have ever programmed in C#, the syntax is close enough that you should be able to provide constructive criticism about the code sample.

Eric Gunnerson’s blog on msdn.com provides details about what’s wrong with the code from a C# programmer’s perspective.

Assuming that I didn’t know C# and wasn’t familiar with HTML, I would suspect that appending the input string to “<h1>Values</h1>” would cause the input string to be adjacent to the label. For example: ValuesLike this. This is not the case for normal HTML because the </h1> tag forces a new paragraph (caveat: this might be overridable with CSS but I’m not that much of a CSS expert to know).

The point of the first code sample was to provide an example of a program that wasn’t C++ but was similar to C++ and to examine it from a C++ coder’s perspective.

This is the C# code for your convenience:

enum ResponseType { ReturnValues, InvalidInput };

string CreateWebText(string userInput, ResponseType operation) {
   switch (operation) {
      case ResponseType.ReturnValues:
         userInput = "<h1>Values</h1>" + FilterOutBadStuff(userInput);
         break;
      case ResponseType.InvalidInput:
         userInput = "<h1>Invalid</h1>" + FilterOutBadStuff(userInput);
         break;
   }
   return userInput;
}
Listing 2: C# Code Example

The second code sample, shown in Listing 3, asks if a number can be assigned to a structure. The trick in Listing 3 is that the code looks like it’s doing one thing when it’s really doing something else. When 7 is being assigned to the Fred structure, the compiler looks for a conversion for 7 to the Fred structure. One is available with Fred’s constructor. By tracing this code in C++ Builder, you’ll be able to see what happens. A std::vector with 7 empty elements is instantiated. The std::vector::operator=() method copies the temporarily instantiated empty vector to f. The value that is written to cout is 0 because the temporary vector was instantiated with 7 empty elements.

struct Fred {
  Fred(int n): v(n) {}
  std::vector<int> v;
};

int main() {
  using namespace std;
  Fred f(1);
  f.v[0] = 5;
  cout << f.v[0] << endl;
  f = 7;          // is this legal?
  cout << f.v[0]; // what is output here?
}
Listing 3: Is this code legal?

Array destruction

An array that is instantiated with the new[] operator should also be deleted using the delete[] operator. Write a program that proves that the destructors for an array are not called when the array was instantiated with new [] and the array was deleted with delete (without the delete[] syntax).

My first version of the array destruction test in Listing F did not use the VCL (a Borland C++ compiler feature) and an access violation was thrown at runtime. I tried to wrap the delete with a try/catch, but the exception still wasn’t caught. The debugger told me that an EAccessViolation exception was being thrown and the C++ Builder Help told me that it was defined in the VCL. So I converted the program to use the VCL and tried it again. The VCL version does not cause an access violation at runtime, so I removed the try/catch block in the code.

// An array that is instantiated with the new[] operator 
// should also be deleted using the delete[] operator.  
// Write a program that proves that the destructors for 
// an array are not called when the array was instantiated 
// with new [] and the array was deleted with delete 
// (without the delete[] syntax).

// This program took 15 minutes to write and debug.

#include <vcl.h>
#include <iostream>

using namespace std;   // okay for small programs

int g_LiveInstances = 0;

struct Trivial {
  Trivial() {
    cout << "Creating object #" << ++g_LiveInstances << endl;
  }
  virtual ~Trivial() {
    cout << "Deleting an object" << endl;
    --g_LiveInstances;
  }
};

int main(int, char**) {
  Trivial *p = new Trivial[5];
  delete p;

  // This should show:
  //    Number of Trivial instantiations remaining: 4
  cout << "Number of Trivial instantiations remaining: ";
  cout << g_LiveInstances << endl;
  return 0;
}
Listing F: Array Destruction Test

Show an example of a valid C program that fails to compile in C++.

Use any C++ keyword that doesn’t exist in C. The class keyword is a good example: int class = 5;

Show an example of a valid C program that compiles cleanly in C++ but gives a different result.

This one is a little bit trickier. We want some feature in C++ that wasn’t backwards compatible with C. Thinking outside of the box, you could come up with:

#ifdef __cplusplus
  printf("I am C++\n");
#else
  printf("I am C\n");
#endif

The interviewer might accept that the __cplusplus compiler directive was not defined in a normal C program.

However, keeping with the spirit of the question, there are a couple reasonable solutions available:

1. C++ comments use both // and /* */ whereas standard C uses only //. If you can construct an expression in a C program that contains /* and */, it will compile cleanly in both compilers but give different runtime results.

2. Literal characters in C (such as ‘a’), are of type int. Therefore, in C, sizeof(‘a’) is the same as sizeof(int). Literal characters in C++ are of type char. On all Borland C++ compilers, sizeof(int) != sizeof(char).

David Tribble’s web site contains a detailed synopsis of the incompatibilities between C and C++.

Why won’t this compile?

for (int i = 0; i < 10; i++) {
  for (int k = 0; k < 10; k++) {
    if (e == 0) goto next_i;
  }
  next_i;
}

 

The next_i label needs a colon (:) after it, like this: next_i:

Is there a “placement delete”?

No, but you can write your own. Stroustrup discusses this on his C++ FAQ page at att.com.

Write a program whose output is its own source code.

A program whose output is its own source is called a quine. Some people think those kinds of programs are interesting. The techniques involved in making a quine have applications in compiler, decompiler, and encryption technologies.

Depending on the mood of the interviewer, you could initially try:

cout << "its own source code";

which the interviewer would have to admit does answer the question. A solution that is closer to the spirit of the question is in Listing L.

The interviewer might insist on a self-contained solution that doesn’t use external files or resources. I found one on the Internet that is only four lines of code.

#include<stdio.h>
#include<conio.h>
#include<iostream.h>

int main(int, char**) {
  FILE *fp;
  fp = fopen("myself.cpp","r");
  char buffer[80];
  while (fgets(buffer,sizeof(buffer),fp)) {
    cout << buffer;
  }
  return 0;
}
Listing L: A program whose output is its own source code.

THE END

 

some useful tips (mostly for myself)