Академический Документы
Профессиональный Документы
Культура Документы
What is inheritance?
What is encapsulation?
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.
What is polymorphism?
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.
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 :)
What is downcasting?
void f()
{
B* pb = new D; // unclear but
ok
B* pb2 = new B;
D* pd = dynamic_cast<D*>(pb); // ok: pb
actually points to a D
...
D* pd2 = dynamic_cast<D*>(pb2); //error: pb2
points to a B, not a D
// pd2 ==
NULL
...
}
This type of conversion is called a "downcast" because it moves a pointer down a class hierarchy,
from a given class to a class derived from it.
What is a class?
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.
What is the difference between struct and class?
2. Default inheritance for struct is public, where as for class the default inheritance is
private.
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++ !
What is the virtual destructor. When and why do you need it? (Be surprised if you are not asked
this question!)
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.
When and why should you avoid a multiple inheritance. What are the good examples of MI usage?
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.
Expect bunch of Design Patterns questions such as: "Describe pattern blah-blah-blah", "How and
when to use a pattern ..." Not many people use them yet (the shame!), but many like to ask such
questions on the interview.
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.
What is a pure virtual method (function)? What is the syntax for a pure virtual method? What is an
abstract class?
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.
In C++, how do I force derived classes to implement a virtual method from the base class?"
What is a reference?
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.
In C++ I can declare a reference to a pointer. Can I not also declare a pointer to a reference? Why
or How?
No, you cannot. It is explicitly stated in C++ spec that pointers to references are prohibited.
What is a stream?
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.
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.
Question regarding constructor and destructor : What would be the output of the program1? Could
you explain the role of virtual destructor ?
1. A Constructor
2. B Constructor
3. C Constructor
4. C Destructor
5. B Destructor
6. A Destructor
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.
o Step 3: A::test() (because class C is a friend class of A and, hence, has an access to private
members of the class A)
public:
A();
}
A::A()
:j(0), i(j)
{}
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.
How does C++ copy objects if your program doesn't provide a copy constructor?
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.
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.
What happens when the object is being destructed (or, in other words, what's the order of
object destruction)?
When an object goes out of scope or is deleted, the sequence of events in its complete destruction
is as follows:
1. The class's destructor is called, and the body of the destructor function is executed.
2. Destructors for nonstatic member objects are called in the reverse order in which they
appear in the class declaration. The optional member initialization list used in
construction of these members does not affect the order of construction or destruction.
3. Destructors for nonvirtual base classes are called in the reverse order of declaration.
4. Destructors for virtual base classes are called in the reverse order of declaration.
(Very important question - many people fail here despite this question is as stupid(as all
others!!!) Mark which lines are wrong (you may be asked how references or/and pointers
are initialized)?
int a = 10;
int *b = a;
int *c = &a;
int &d = a;
int &e = &a;
int &f = *c;
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;
Write all constructors for the following classes so that DoorWithLock class could be
called with the constructor DoorWithLock(1,300,400,300), where 1,300,400,300 are the
default parameters:
class Door{ private: int m_Height, m_Width; }
class Lock{ private: int m_Type; }
class DoorWithLock{ private: Lock lock; int m_Owner; }
This should go like this:
class Lock
{
public:
Lock(int Type = 300)
{
m_Type = Type;
}
private:
int m_Type;
};
What's wrong with the following code? Could you suggest alternative way of array's
initialization?
char *pArray = new char[256];
for( int i = 0; i < 256; i++ )
{
pArray[i] = 0;
}
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.
3
2
3
4
The answer in this particular case is B::foo(). If you would create an object of type A, A::foo()
would be called.
Const
What does the following constant mean? const int f(const int &i) 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)
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.
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.
How can you create a C++ function that is callable from C-compiled code?
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".
What are the limitation when calling C++ functions from C-compiled code?
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)
Could you use the following function in C: void foo(int i = 0; int j);
No, you cannot use this signature in C, since default parameters (int i = 0) are defined only in
C++.
Exception Handling
Why might you need exception handling be used in the constructor when memory allocation is
involved?
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.
What are the advantages of templates in C++?
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.
Write a generic class, which is container of indexes and numbers, with function determining the
minimal number from the numbers of the container.
STL
2. The major difference is the way of element access. Vector elements may accessed
randomly while list elements must be accessed sequentially.
3. Iterators are different as a result of the first item: list support bi-directional iterators while
vector uses random access iterator.
4. Some methods are difference (for example, only list supports merge and splice, adds
push_front and pop_front etc.
What is an iterator?
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.
What is stl::string?
class itself, char_traits, allocator. char_traits class is templatized class of one char's characterstics.
Which of the following containers do not belong to STL: queue, list, vector?
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
If you have a union consisting of integer (4 bytes) and double (8 bytes) what would be minimal
size allocated for that union?
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
How many internal nodes does a full binary tree of height n have?
2^^n - 1
Write a function that swaps the values of two integer variables without using any other temporary
variable; the function should have the following prototype: void swap (int& x, int&y)
void swap (int& x, int&y)
{
x = y – x;
y = y - x;
x = y + x;
}
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.
What's wrong with the following program? Would would be returned from foo()?
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.
What's the correct way to determing the size (number of elements) of an array?
a) size(array)/size(*array)
b) size(*array)/size(array)
c) size(array)/sizeof(array)
d) sizeof(array)/size(array)
e) sizeof(array)/sizeof(*array)
f) sizeof(*array)/sizeof(array)
Honestly, none of them :) You should use sizeof(array)/sizeof(array[0]) to get it.