Common C/C++ Interview QuestionsSend your question/answer Concepts & General Questions
An object-oriented programming term. The ability of a subclass to take on the
characteristics of the class it's based on. If the characteristics of the parent
class change, the subclass on which it is based inherits those characteristics.
An object-oriented programming term for the ability to contain and hide
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.
Encapsulation.
An object-oriented programming term. The ability to have methods with the same
name, but different content, for related classes. The procedure to use is
determined at run time by the class of the object. For example, related objects
might both have Draw methods. A procedure, passed such an object as a parameter,
can call the Draw method without needing to know what type of object the
parameter is.
Virtual base classes offer a way to save space and avoid ambiguities
in class hierarchies that use multiple inheritance. Each nonvirtual object
contains a copy of the data members defined in the base class. When a base class
is specified as a virtual base, it can act as an indirect base more than once
without duplication of its data members. A single copy of its data members is
shared by all the base classes that use it as a virtual base.
inline keyword before name of the function allows the compiler to insert
a copy of the function body into each place the function is called. Therefore,
the size of the code is increasing, but speed of execution is also increasing.
You should mention that there are circumstances (e.g. recursive functions) when
compiler is allowed to ignore inline keyword.
Overloading is the practice of supplying more than one definition for a given
function name in the same scope. The compiler is left to pick the
appropriate version of the function or operator based on the arguments with
which it is called. Overriding refers to the virtual functions, i.e. functions
that ensure that the correct function is called for an object, regardless of the
expression used to make the function call. For example, if the same function
with virtual attribute is declared in base and derived class, the function from
the derived class is invoked for objects of the derived class, even if it is
called using a pointer or reference to the base class.
I was actually asked this question at one of my interviews. I guess the single
purpose of this question is to paralyze the interviewee. In my case the
interviewer has achieved the goal and I am glad I did not pass an interview to
that company. The interviewer actually tried to fetch a basic overview of C++
paradigms and design patterns (this envelope/letter paradigm is described in the
book of Coplien from 1995) While I do not question the importance of design
patterns, all I was talking to agreed that in this form the question demonstrate
inability of the interviewer to conduct the interview. You may safely ignore
this question if you asked :)
Consider the following example:
According to Rumbaugh & Co, "an object class describes a group of
objects with similar properties (attributes), common behavior (operations),
common relationships to other objects, and common semantics." In one word
class is a type. This is a way to create a new types of objects in
C++. You may then proceed to explanation on the class structure, level of access
and so on.
There are few differences:
A namespace allows you to resolve conflict of the global identifiers when you
use, for example, two different libraries of different vendors, which use the
same names. Of course, if the vendors of libraries also use the same name for
the namespace, you cannot resolve the name conflict with namespace feature of
C++ !
Destructor implemented by declaring a base class's destructor with the keyword
virtual.
A virtual destructor ensures that, when delete is applied to a base
class pointer or reference, it calls the destructor implemented in the derived
class, if an implementation exists.
While this question seems to be a silly one, it is easiest to be prepared to. I
think it worth to mention Meyers, Gamma, Coplien, Stroustrup, Schildt etc.
You should avoid so called diamond structure where a class derives from several
base classes which, in turn, have common base class. Good example of MI is an
ATL which is based on the idea of MI.
This question, in fact, is quite simple. I will not give you an example here,
but look at auto_ptr (STL) and CComPtr (ATL) in order to provide your own
implementation of reference-counted smart pointer class. Check also http://web.ftech.net/~honeyg/articles/smartp.htm
Singleton is a class that can have only one instance. For singleton example, see
Singleton pattern in "Design Patterns" of E.Gamma, etc.
You must read the book of E.Gamma, "Design Patterns". If you missed
this book, it's time to have one at your home bookshelf.
Pure virtual function is a function that declared with "=0;"
specifier. Pure virtual function does not have body and must be overridden in
the derived class. The syntax for pure virtual function is
virtual void foo() = 0;Abstract class is a class with at least one pure virtual function.
Use pure virtual function.
A reference is a quantity that holds the address of an object but behaves
syntactically like that object. A reference cannot exist without object and must
be initialized.
No, you cannot. It is explicitly stated in C++ spec that pointers to references
are prohibited.
Stream is a sequence of bytes.
Shortly, friend class or function is a class or a function that declared friend
of an other class. The idea behind friend class is to provide the access to the
private and protected members or member functions of the friend class. There is
a lot of controversial opinions on this topic and you should not usually use
friends as it is a hole in your design. One of the examples where it's used is a
momento design pattern.
1 or 2. It may either mean a single pointer to an int or a pointer to array of
int[s].
The only implicit argument I found in C++ is this. I guess this is what
the answer assumes. this is passed to member function call as an implicit
argument of member function (you may see it in assembler)
Initialization
This type of question is supposed to get you out of the saddle. In constructor,
of course.
This was a simple question to check your basic understanding:
In C++ the initialization of members is performed in order of their declaration.
'i' was declared before 'j'. Therefore, 'i' will be initialized first and the
value of 'j' is undefined at that time.
If you do not supply a copy constructor, the compiler attempts to generate one.
A compiler-generated copy constructor sets up a new object and performs a
memberwise (not bitwise!!!) copy of the contents of the object to be copied. If
base class or member constructors exist, they are called; otherwise, bitwise
copying is performed.
You should understand the difference between scalar and vector deleting of the
objects. If you allocate memory for a vector of objects and
then delete the pointer to the vector, only the destructor of the first element
of the vector will be deallocated. To ensure all elements of the vector are
being destroyed, you should use the following syntax:
delete [] pobj; // must delete [] pArray; // should Strictly saying, for simple types such as char, int, etc. you don't have to use delete[], but it is highly recommended to use the same form delete[] for all vectors.
When an object goes out of scope or is deleted, the sequence of events in its
complete destruction is as follows:
One thing that you must remember as the word c++ itself is references are
always initialized with value, while pointers are always initialized with
address. Once you remember this simple rule, you'll be able to easily answer
this type of question.
int a = 10; // error cannot convert from int to int*: int *b = a; int *c = &a; int &d = a; // error cannot convert from int* to int&: int &e = &a; int &f = *c;
This should go like this:
Nothing wrong really with this code. You may mention that 0 is not char and
compiler may complain, that "cannot convert from int to char".
However, most compiler would eat this initialization without problem whatsoever.
You may mention that other ways of array initialization are using memset(pArray,
0, 256), ZeroMemory() (if we are talking about Windows) or stl's for_each()
algorithm. You might want to mention also that in this particular case you would
use stl::string rather than char* (but this really depends on context of the
question)
Operators
Yes, but it's not recommended. It is extremely bad and dangerous practice!
Binding
Virtual attribute for a functions assumes that its body will be possibly
overridden in the derived class. Non-virtual function is always called from the
class where it is defined. You may also say that "virtual" functions
implement polymorphism (by the way, it is highly recommended to put all you know
about virtual and polymorphism in the answer. Do not follow blindly to all these
answers.) Again, it is quite important that you demonstrate the understanding of
the intent of virtual function to be overwritten in the derived class.
The answer in this particular case is B::foo(). If you would create an object of
type A, A::foo() would be called.
4. foo() uses C naming convention in C++ program.
Const
Function that accepts "const int" argument (i.e. value of the argument
cannot be changed), returning "const int" and cannot modify the
object's members (last const)
Declaring a member function with the const keyword specifies that the function
is a "read-only" function that does not modify the object for which it
is called. A constant member function cannot modify any data members or call any
member functions that aren't constant.
For simple types (int, char etc.) there is no difference. For
parameters-pointers it means that the value it points to cannot be modified
(however, you may move the pointer itself, since it will be only copy of the
pointer of the original object.) For references it means values of the object
cannot be modified. Parameter that is not const pointer involves a copy
constructor, that is kind of waste for big objects)
Reference
"important" is inappropriate word, because it depends on the
situation. One thing that might come to mind is that C++'s exception mechanism
is able to catch exceptions of any type, for example a custom class. To
avoid a copy of the exception object during exception twice, you may
use a references. In this case the exception object is initialized to point to
the actual thrown exception object. Exception is always thrown by value.
Therefore, if you use by-value parameter in catch statement, you force the
compiler to invoke the copy constructor twice.
You cannot return the address of a local variable, because it will be destroyed
when the function returns.
It's not really a swap function, because the value of x will be hopelessly lost
after the first assign.
The values of x and y will not be changed (they will be changed inside of swap
function, but not for the outside world.
When you return the object by value, copy constructor is called, which is not
the case when you return by reference (see item 22 of Scott Meyers.) But see
item 23 for discussion when you don't have to pass by reference.
Static members
Static member variables are the same value for all instances of the class.
Static member functions are not really the members. The idea is that you may
call the static member function from any other class, if you specify the base
class name where the static member function was declared. Of course, static
member function cannot change the members of the class.
C/C++ Interoperability
You should use extern "C" for functions, compiled by C compiler and
called within a C++ class. You should do that to force the linker to resolve the
function name (precisely, the mangling of the name) correctly.
What a perverted logic! Why would you need this?! Anyway, if you need this, you
should know that only static or friend functions of the class may be called from
C program. If you don't have static function, you should create a static wrapper
around the member function. Then, declare the function with extern
"C".
See previous answer. Only static and friend functions might be called from C
program.
The major difference is that string in C is a char*, i.e. stream, while C++'s
string is a class that works with streams.
Shortly speaking, C++ is an object-oriented language (well, kind of), which
supports such OO terms as encapsulation, inheritance and polymorphism. C is a
functional programming language, which has no meaning of object (here you may
shine with you erudition, mentioning object-oriented C, which does know about
objects)
No, you cannot use this signature in C, since default parameters (int i = 0) are
defined only in C++.
Exception Handling
Disadvantage is a slight overhead imposed by implementing of exception handling
mechanism. Advantage is "bullet-proof" program. With exception
handling you have a mechanism which guarantee you control over program behavior
despite the errors that might be in your program. With try-catch block you
control not even given block of the program, but also all underlying function
calls.
Your first reaction should be: "Never use memory allocation in the
constructor." Create a separate initialization function to do the job. You
cannot return from the constructor and this is the reason you may have to use
exception handling mechanism to process the memory allocation errors. You should
clean up whatever objects and memory allocations you have made prior to throwing
the exception, but throwing an exception from constructor may be tricky, because
memory has already been allocated and there is no simple way to clean up the
memory within the constructor.
Templates
Template functions allow you to define the same behavior for different types.
Templates have several advantages.
Firstly, they allow to avoid inappropriate multiple inheritance, where one of the inherited classes is just type to be managed. Secondly, they allow to inherit from "unknown" type, therefore creating "management" class for unknown type. Thirdly, templates allow to create "general" classes that is especially useful for all kind of type-safe collection classes. One good use is building framework classes that unite and hide several internal implementation classes (which can be non-template). This makes it easy for a beginner to use a big integrated complex functional class and still allows advanced users to rewrite portions of actual implementation. Drop me email if you think about more advantages. This is pretty open discussion.
You may think I am kidding. No, this is one of the question I was actually asked
at the interview. I was quite puzzled by this question. Say some numbers: 100,
1000. Number does not matter. What does matter in this case is your real
knowledge of templates and you will either fail during further questions or
succeed.
I guess you should write something like the program 5.
STL
There are few differences:
Vague question, vague answer. You should ask the interviewer which iterator it
means: as a general term, an STL object or a design pattern? Regardless of the
answer, you should answer that iterator is an object that provides a sequential
access to the elements of the other objects without knowing the internal
structure of the controlled object.
Again, context is important. Vector is a one-dimensional array. It's also an STL
class while array is a data type.
This is from the collection of dumb questions. MSDN is there precisely for that!
However, for the documentation purposes, remove() removes elements by value,
while erase() uses iterator for the same purpose.
First, I would strongly suggest to open any data structures book and to refresh
your knowledge about hash tables. The advantage of hash table is quick access to
stored elements. Disadvantage is that there no universal function to resolve the
hash conflict and each and every way (chaining, rehashing etc.) has advantages
and disadvntages for various cases.
typedef basic_string<char> string;The type describes a specialization of template class basic_string
for elements of type char
class itself, char_traits, allocator. char_traits class is templatized class of
one char's characterstics.
All three belong to STL.
As a matter of fact (I though originally it was a joke) you might be required to
write _any_ function from algorithm collection (I guess way to go for a standard
committee)
UML
It was quite interesting story, because I wrote the difference in terms of COM
and the interviewer meant C++. The only problem that when he drew the question,
it turned out that he hardly knows terminology himself. Trust me, in terms of
C++ (to be precise in terms of UML) there is NO diference between aggregation
and containment. Aggregation IS containment and containment IS aggregation.
There is a difference, however, between aggregation and composition. This
question should sound: "What's the difference between aggregation and
composition in terms of UML?". Back to answer. The difference between
aggregation and composition is life term of participating objects. Aggregated
object can exist without container. Composited object is managed by it's
container and cannot live without it. Interviewer would probably expect that you
will say that composition implemented by creating object by value and
aggregation implemented by creating object by reference (or pointer), but
strictly saying it's not true. The true difference is who manages the life cycle
of the aggregated object.
Memory
8.
Input/Output
No comments, please. You don't have to know what are those function. As an
registrar, I'll document here that seekp() finds the position of the internal
pointer of output stream, while seekg() finds the position of the internal
pointer of the input stream. Now who is about to tell me what kind of person
gave such name to those functions?!
Miscellaneous
2^^n - 1
Theoretically, this is an attempt to test you ability to concentrate on details.
Practically, this is as stupid question as all others in similar tests. For
records, the signature of printf() is int printf(char *format, ...) and return
value is number of characters written to the output stream.
Quite a few things. Main() must start with lower case (C++ is case sensitive).
Bad style. You would not want to accept a programmer who does such things :) int
*z = &x++ is unlikely to pass the compilation and intention of the author is
not clear. In either case, this code will return just garbage.
int printf(char *format,...); Please, do not make comments! :)
Compiler will warn that "cannot convert from int to int*".
Honestly, none of them :) You should use sizeof(array)/sizeof(array[0]) to get
it.
|