C++ : Basics of the paradigm


Q12: What is a class?
A: A class defines a data type, much like a struct would be in C.  In a CompSci
sense, a type consists of two things: a set of values *and* a set of operations
which operate on those values.  Thus `int' all by itself isn't a true `type'
until you add operations like `add two ints' or `int*int', etc.  In exactly the
same way, a `class' provides a set of (usually `public') operations, and a set
of (usually non-public) data bits representing the abstract values that
instances of the type can have.  From a C language perspective, a `class' is a
`struct' whose members default to `private'.

Q13: What is an object?
A: An object is a region of storage with associated semantics.  After the
declaration `int i;', we say that `i is an object of type int'.  In C++/OOP,
`object' is usually used to mean `an instance of a class'.  Thus a class
defines the behavior of possibly many objects (instances).

Q14: What is a reference?
A: A reference is an alias (an alternate name) for an object.  It is frequently
used for pass-by-reference; ex:

	void swap(int& i, int& j)
	  int tmp = i;
	  i = j;
	  j = tmp;

	  int x, y;

Here `i' and `j' are aliases for main's `x' and `y' respectively.  The effect
is as if you used the C style pass-by-pointer, but the `&' is moved from the
caller into the callee.  Pascal enthusiasts will recognize this as a VAR param.

Q15: What happens if you assign to a reference?
A: Assigning to a reference changes the referred-to value, thus a ref is an
`Lvalue' (something that can appear on the `L'eft-hand-side of an assignment
statement) for the referred-to value.  This insight can be pushed a bit farther
by allowing references to be *returned*, thus allowing function calls on the
left hand side of an assignment stmt.

Q16: How can you reseat a reference to make it refer to a different object?
A: Unlike a pointer, once a reference is bound to an object, it can NOT be
`reseated' to another object.  The reference itself isn't an object; you can't
separate the reference from the referred-to-object.  Ex: `&ref' is the address
of the referred-to-object, not of the reference itself.

Q17: When should I use references, and when should I use pointers?
A: Old line C programmers sometimes don't like references since the reference
semantics they provide isn't *explicit* in the caller's code.  After a bit of
C++ experience, however, one quickly realizes this `information hiding' is an
asset rather than a liability.  In particular, reuse-centered OOP tends to
migrate the level of abstraction away from the language of the machine toward
the language of the problem.

References are usually preferred over ptrs whenever you don't need `reseating'
(see early question on `How can you reseat a reference').  This usually means
that references are most useful in a class' public interface.  References then
typically appear on the skin of an object, and pointers on the inside.

The exception to the above is where a function's parameter or return value
needs a `sentinel' reference.  This is usually best done by returning/taking a
pointer, and giving the nil ptr (0) this special significance (references
should always alias *objects*, not a dereferenced nil ptr).

Q18: What are inline fns? What are their advantages? How are they declared?
A: An inline function is a function which gets textually inserted by the
compiler, much like a macro.  Like macros, performance is improved by avoiding
the overhead of the call itself, and (especially!) by the compiler being able
to optimize *through* the call (`procedural integration').  Unlike macros,
arguments to inline fns are always evaluated exactly once, so the `call' is
semantically like a regular function call only faster.  Also unlike macros,
argument types are checked and necessary conversions are performed correctly.

Beware that overuse of inline functions can cause code bloat, which can in
turn have a negative performance impact in paging environments.

They are declared by using the `inline' keyword when the function is defined:
	inline void f(int i, char c) { /*...*/ }   //an inline function
or by including the function definition itself within a class:
	class X {
	  void f(int i, char c) { /*...*/ }   //inline function within a class
or by defining the member function as `inline' outside the class:
	class X {
	  void f(int i, char c);
	inline void X::f(int i, char c) {/*...*/} //inline fn outside the class

Generally speaking, a function cannot be defined as `inline' after it has been
called.  Inline functions should be defined in a header file, with `outlined'
functions appearing in a `.C' file (or .cpp, etc; see question on file naming