C++ Language-specific Answers
by Curtis Krauskopf
One strategy to use when answering a language issue
question is to examine the question from various perspectives.
Some perspectives to consider are:
- the language author wants to prevent ambiguities
- the C++ compiler vendor want to simplify the compiler's
implementation
- the code writer wants clear rules for implementing
a feature
- the maintenance programmer needs to understand existing
code
- legacy code should not be broken by new features
The best answer is one that acknowledges the tradeoffs
that were made to accommodate one or more of the above
groups. When reviewing your video or audio tape, give
yourself extra credit for each group that you mention
and their tradeoffs.
Q1) 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.
A1) 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).
Q2) Can I drop the [] when deleting an array of some
built-in type (char, int, etc)?
A2) No. Marshall Cline's C++ FAQ Lite contains a good
explanation at parashift.com.
Q3) What is an example of when a destructor is NOT
called at the end of scope?
A3) 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.
Q4) Explain stack unwinding.
A4) 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.
Q5) When I write a derived class's destructor, do I
need to explicitly call the destructor for my base class?
A5) Marshall Cline's C++ FAQ Lite answers this question
with "No". A more explicit explanation with an example
is at parashift.com.
Q6) Explain the difference between a class and an object.
A6) 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.
Q7) Explain the difference between a struct and a class.
A7) 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.
Q8) What is difference between malloc()/free() and
new/delete?
A8) 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[]).
|