Category : C++ Source Code
Archive   : CPPFAQ93.ZIP
Filename : CPP-FAQ.1

 
Output of file : CPP-FAQ.1 contained in archive : CPPFAQ93.ZIP
Article 43788 of comp.lang.c++:
Xref: uuneo comp.lang.c++:43788 news.answers:10002
Newsgroups: comp.lang.c++,news.answers
Path: uuneo!sugar!menudo.uh.edu!swrinde!cs.utexas.edu!uunet!gatech!news.ans.net!rpi!clarkson!news.clarkson.edu!cline
From: [email protected] (Marshall Cline)
Subject: comp.lang.c++ FAQ (part 1 of 4)
Message-ID:
Sender: [email protected]
Nntp-Posting-Host: cheetah.ece.clarkson.edu
Reply-To: [email protected] (Marshall Cline)
Organization: Paradigm Shift, Inc (Reuse/C++/OOD training, C++ libraries)
Date: Fri, 9 Jul 1993 11:36:49 GMT
Approved: [email protected]
Expires: Mon, 9 Aug 1993 10:30:14 GMT
Lines: 830

To all:

Until Jamshid Afshar and I figure out the appropriate C++FAQ posting guidelines
(ie: whether we have to continue posting it in several pieces), I decided to
post the latest update in four big files (4*40k=160k) . . .

Marshall


==============================================================================

Document: Frequently-Asked-Questions for comp.lang.c++
Revision: 09-July-93

Author: Marshall P. Cline, Ph.D.
Paradigm Shift, Inc.
One Park St. / Norwood, NY 13668
voice: 315-353-6100
fax: 315-353-6110
email: [email protected]

Copyright: Copyright (C), 1991-93 Marshall P. Cline, Ph.D.
Permission to copy all or part of this work is granted,
provided that the copies are not made or distributed
for resale (except nominal copying fee may be charged),
and provided that the NO WARRANTY, author-contact, and
copyright notice are retained verbatim & are displayed
conspicuously. If anyone needs other permissions that
aren't covered by the above, please contact the author.

NO WARRANTY: THIS WORK IS PROVIDED ON AN "AS IS" BASIS. THE AUTHOR
PROVIDES NO WARRANTY WHATSOEVER, EITHER EXPRESS OR
IMPLIED, REGARDING THE WORK, INCLUDING WARRANTIES WITH
RESPECT TO ITS MERCHANTABILITY OR FITNESS FOR ANY
PARTICULAR PURPOSE.

Availability: This is available via anonymous ftp
from: sun.soe.clarkson.edu [128.153.12.3]
in the file: pub/C++/FAQ

Without FTP: You can also get it by sending electronic mail:
| To: [email protected]
| Subject: send C++/FAQ
This will help those who don't have ftp.

(NOTE: I hear the mail server is down; if you have problems,
send details and I'll look into it).

See also: comp.lang.c's FAQ appears at the beginning of every
month in that newsgroup, and is maintained by
Steve Summit ([email protected]).

==============================================================================
SUBSECTION: Table of Contents
==============================================================================

PART01 -- Introduction and table of contents
Table of Contents
Nomenclature and Common Abbreviations

PART02 -- Environmental/managerial issues
Q1: What is C++? What is OOP?
Q2: What are some advantages of C++?
Q3: Who uses C++?
Q4: Are there any C++ standardization efforts underway?
Q5: Where can I ftp a copy of the latest ANSI-C++ draft standard?
Q6: Is C++ backward compatible with ANSI-C?
Q7: How long does it take to learn C++?

PART03 -- Basics of the paradigm
Q8: What is a class?
Q9: What is an object?
Q10: What is a reference?
Q11: What happens if you assign to a reference?
Q12: How can you reseat a reference to make it refer to a different object?
Q13: When should I use references, and when should I use pointers?
Q14: What are inline fns? What are their advantages? How are they declared?

PART04 -- Constructors and destructors
Q15: What is a constructor? Why would I ever use one?
Q16: How can I make a constructor call another constructor as a primitive?
Q17: What are destructors really for? Why would I ever use them?

PART05 -- Operator overloading
Q18: What is operator overloading?
Q19: What operators can/cannot be overloaded?
Q20: Can I create a `**' operator for `to-the-power-of' operations?

PART06 -- Friends
Q21: What is a `friend'?
Q22: Do `friends' violate encapsulation?
Q23: What are some advantages/disadvantages of using friends?
Q24: What does it mean that `friendship is neither inherited nor transitive'?
Q25: When would I use a member function as opposed to a friend function?

PART07 -- Input/output via and
Q26: How can I provide printing for a `class X'?
Q27: Why should I use instead of the traditional ?
Q28: Printf/scanf weren't broken; why `fix' them with ugly shift operators?

PART08 -- Freestore management
Q29: Does `delete ptr' delete the ptr or the pointed-to-data?
Q30: Can I free() ptrs alloc'd with `new' or `delete' ptrs alloc'd w/ malloc()?
Q31: Why should I use `new' instead of trustworthy old malloc()?
Q32: Why doesn't C++ have a `realloc()' along with `new' and `delete'?
Q33: How do I allocate / unallocate an array of things?
Q34: What if I forget the `[]' when `delete'ing array allocated via `new X[n]'?

PART09 -- Debugging and error handling
Q35: How can I handle a constructor that fails?
Q36: How can I compile-out my debugging print statements?

PART10 -- Const correctness
Q37: What is `const correctness'?
Q38: Is `const correctness' a good goal?
Q39: Is `const correctness' tedious?
Q40: Should I try to get things const correct `sooner' or `later'?
Q41: What is a `const member function'?
Q42: What is an `inspector'? What is a `mutator'?
Q43: What is `casting away const in an inspector' and why is it legal?
Q44: But doesn't `cast away const' mean lost optimization opportunities?

PART11 -- Inheritance
Q45: What is inheritance?
Q46: Ok, ok, but what is inheritance?
Q47: How do you express inheritance in C++?
Q48: What is `incremental programming'?
Q49: Should I pointer-cast from a derived class to its base class?
Q50: Derived* --> Base* works ok; why doesn't Derived** --> Base** work?
Q51: Does array-of-Derived is-NOT-a-kind-of array-of-Base mean arrays are bad?
Inheritance -- virtual functions
Q52: What is a `virtual member function'?
Q53: What is dynamic dispatch? Static dispatch?
Q54: Can I override a non-virtual fn?
Q55: Why do I get the warning "Derived::foo(int) hides Base::foo(double)"?
Inheritance -- conformance
Q56: Can I `revoke' or `hide' public member fns inherited from my base class?
Q57: Is a `Circle' a kind-of an `Ellipse'?
Q58: Are there other options to the `Circle is/isnot kind-of Ellipse' dilemma?
Inheritance -- access rules
Q59: Why can't I access `private' things in a base class from a derived class?
Q60: What's the difference between `public:', `private:', and `protected:'?
Q61: How can I protect subclasses from breaking when I change internal parts?
Inheritance -- constructors and destructors
Q62: Why does base ctor get *base*'s virtual fn instead of the derived version?
Q63: Does a derived class dtor need to explicitly call the base destructor?
Inheritance -- private and protected inheritance
Q64: How do you express `private inheritance'?
Q65: How are `private derivation' and `containment' similar? dissimilar?
Q66: Should I pointer-cast from a `privately' derived class to its base class?
Q67: Should I pointer-cast from a `protected' derived class to its base class?
Q68: What are the access rules with `private' and `protected' inheritance?
Q69: Do most C++ programmers use containment or private inheritance?

PART12 -- Abstraction
Q70: What's the big deal of separating interface from implementation?
Q71: How do I separate interface from implementation in C++ (like Modula-2)?
Q72: What is an ABC (`abstract base class')?
Q73: What is a `pure virtual' member function?
Q74: How can I provide printing for an entire hierarchy rooted at `class X'?
Q75: What is a `virtual destructor'?
Q76: What is a `virtual constructor'?

PART13 -- Style guidelines
Q77: What are some good C++ coding standards?
Q78: Are coding standards necessary? sufficient?
Q79: Should our organization determine coding standards from our C experience?
Q80: Should I declare locals in the middle of a fn or at the top?
Q81: What source-file-name convention is best? `foo.C'? `foo.cc'? `foo.cpp'?
Q82: What header-file-name convention is best? `foo.H'? `foo.hh'? `foo.hpp'?
Q83: Are there any lint-like guidelines for C++?

PART14 -- C++/Smalltalk differences and keys to learning C++
Q84: Why does C++'s FAQ have a section on Smalltalk? Is this Smalltalk-bashing?
Q85: What's the difference between C++ and Smalltalk?
Q86: What is `static typing', and how is it similar/dissimilar to Smalltalk?
Q87: Which is a better fit for C++: `static typing' or `dynamic typing'?
Q88: How can you tell if you have a dynamically typed C++ class library?
Q89: Will `standard C++' include any dynamic typing primitives?
Q90: How do you use inheritance in C++, and is that different from Smalltalk?
Q91: What are the practical consequences of diffs in Smalltalk/C++ inheritance?
Q92: Do you need to learn a `pure' OOPL before you learn C++?
Q93: What is the NIHCL? Where can I get it?

PART15 -- Reference and value semantics
Q94: What is value and/or reference semantics, and which is best in C++?
Q95: What is `virtual data', and how-can / why-would I use it in C++?
Q96: What's the difference between virtual data and dynamic data?
Q97: Should class subobjects be ptrs to freestore allocated objs, or contained?
Q98: What are relative costs of the 3 performance hits of allocated subobjects?
Q99: What is an `inline virtual member fn'? Are they ever actually `inlined'?
Q100: Sounds like I should never use reference semantics, right?
Q101: Does the poor performance of ref semantics mean I should pass-by-value?

PART16 -- Linkage-to/relationship-with C
Q102: How can I call a C function `f()' from C++ code?
Q103: How can I create a C++ function `f()' that is callable by my C code?
Q104: Why's the linker giving errors for C/C++ fns being called from C++/C fns?
Q105: How can I pass an object of a C++ class to/from a C function?
Q106: Can my C function access data in an object of a C++ class?
Q107: Why do I feel like I'm `further from the machine' in C++ as opposed to C?

PART17 -- Pointers to member functions
Q108: What is the type of `ptr-to-member-fn'? Is it diffn't from `ptr-to-fn'?
Q109: How can I ensure `X's objects are only created with new, not on the stack?
Q110: How do I pass a ptr to member fn to a signal handler,X event callback,etc?
Q111: Why am I having trouble taking the address of a C++ function?
Q112: How do I declare an array of pointers to member functions?

PART18 -- Container classes and templates
Q113: How can I insert/access/change elements from a linked list/hashtable/etc?
Q114: What's the idea behind `templates'?
Q115: What's the syntax / semantics for a `function template'?
Q116: What's the syntax / semantics for a `class template'?
Q117: What is a `parameterized type'?
Q118: What is `genericity'?
Q119: How can I fake templates if I don't have a compiler that supports them?

PART19 -- Nuances of particular implementations
Q120: Why don't variable arg lists work for C++ on a Sun SPARCstation?
Q121: GNU C++ (g++) produces big executables for tiny programs; Why?
Q122: Is there a yacc-able C++ grammar?
Q123: What is C++ 1.2? 2.0? 2.1? 3.0?
Q124: How does the lang accepted by cfront 3.0 differ from that accepted by 2.1?
Q125: Why are exceptions going to be implemented after templates? Why not both?
Q126: What was C++ 1.xx, and how is it different from the current C++ language?

PART20 -- Miscellaneous technical and environmental issues
Miscellaneous technical issues:
Q127: Why are classes with static data members getting linker errors?
Q128: What's the difference between the keywords struct and class?
Q129: Why can't I overload a function by its return type?
Q130: What is `persistence'? What is a `persistent object'?
Miscellaneous environmental issues:
Q131: Is there a TeX or LaTeX macro that fixes the spacing on `C++'?
Q132: Where can I access C++2LaTeX, a LaTeX pretty printer for C++ source?
Q133: Where can I access `tgrind', a pretty printer for C++/C/etc source?
Q134: Is there a C++-mode for GNU emacs? If so, where can I get it?
Q135: What is `InterViews'?
Q136: Where can I get OS-specific questions answered (ex:BC++,DOS,Windows,etc)?
Q137: Why does my DOS C++ program says `Sorry: floating point code not linked'?

==============================================================================
SUBSECTION: Nomenclature and Common Abbreviations
==============================================================================

Here are a few of the abbreviations/etc used in this article:

term meaning
==== ===========
ctor constructor
copy-ctor copy constructor (also `X(const X&)', pronounced `X-X-ref')
dtor destructor
fn function
fns functions
ptr pointer, a C/C++ construct declared by: int * p;
ref reference, a C++ construct declared by: int & r;
const a C++ keyword which is short for `constant'
OO object-oriented
OOP object-oriented programming
OOPL object-oriented programming language
method an alternate term for `member function'
message an alternate term for `invoking a member function'
NULL the `zero' or `empty' pointer (`NULL' in C, `0' in C++)

==============================================================================

**** PART 02 -- Environmental/managerial issues ****

==============================================================================

Q1: What is C++? What is OOP?

C++ can be used simply as `a better C', but that is not its real advantage.
C++ is an object-oriented programming language (OOPL). OOPLs appear to be the
current `top shelf' in the development of programming languages that can manage
the complexity of large software systems.

Some OOP hype: software engineering is `failing' to provide the current users
demands for large, complex software systems. But this `failure' is actually
due to SE's *successes*. In other words, structured programming was developed
to allow software engineers to design/build HUGE software systems (that's a
success). When users saw how successful these systems were, they said, `More
--- give me MOOORRRREEEE'. They wanted more power, more features, more
flexibility. 100K line systems are almost commonplace nowadays, and they still
want more. Structured programming techniques, some say, begin to break down
around 100K lines (the complexity gives the design team too many headaches, and
fixing one problem breaks 5 more, etc). So pragmatics demands a better
paradigm than structured programming. Hence OO-design.

==============================================================================

Q2: What are some advantages of C++?

GROWTH OF C++: C++ is by far the most popular OOPL. Knowing C++ is a good
resume-stuffer. But don't just use it as a better C, or you won't be using all
its power. Like any quality tool, C++ must be used the way it was designed to
be used. The number of C++ users is doubling every 7.5 to 9 months. This
exponential growth can't continue forever(!), but it is becoming a significant
chunk of the programming market (it's already the dominant OOPL).

ENCAPSULATION: For those of you who aren't on a team constructing software
mega-systems, what does C++ buy you? Here's a trivial example. Suppose you
want a `Foible' data type. One style of doing this in `C' is to create a
`Foible.h' file that holds the `public interface', then stick all the
implementation into a `Foible.c' file. Encapsulation (hiding the details) can
be achieved by making all data elements in `Foible.c' be `static'. But that
means you only get one `Foible' in the entire system, which is ok if `Foible'
is a Screen or perhaps a HardDisk, but is lousy if Foible is a complex number
or a line on the screen, etc. Read on to see how it's done in `C' vs `C++'.

MULTIPLE INSTANCES: The `C' solution to the above `multiple instances' problem
is to wrap all the data members in a struct (like a Pascal `record'), then pass
these structs around as if they were the `ComplexNumber' or whatever. But this
loses encapsulation. Other techniques can be devised which allow both multiple
instances and encapsulation, however these lose on other accounts (ex:
typedef'ing `Foible' to be `void*' loses type safety, and wrapping a `void*' in
the Foible struct loses an extra layer of indirection). So the `module'
technique loses multiple instantiations, but the `struct' technique loses
encapsulation. C++ allows you to combine the best of both worlds - you can
have what amount to structs whose data is hidden.

INLINE FUNCTION CALLS: The `encapsulated C' solution above requires a function
call to access even trivial fields of the data type (if you allowed direct
access to the struct's fields, the underlying data structure would become
virtually impossible to change since too many pieces of code would *rely* on it
being the `old' way). Function call overhead is small, but can add up. C++
provides a solution by allowing function calls to be expanded `inline', so you
have: the (1) safety of encapsulation, (2) convenience of multiple instances,
(3) speed of direct access. Furthermore the parameter types of these inline
functions are checked by the compiler, an improvement over C's #define macros.

OVERLOADING OPERATORS: For the `ComplexNumber' example, you want to be able to
use it in an expression `just as if' it was a builtin type like int or float.
C++ allows you to overload operators, so you can tell the compiler what it
means for two complex numbers to be added, subtracted, multiplied, etc. This
gives you: z0 = (z1 + z2) * z3 / z4; Furthermore you might want string1+string2
to mean string concatenation, etc. One of the goals of C++ is to make user
defined types `look like' builtin types. You can even have `smart pointers',
which means a pointer `p' could actually be a user defined data type that
`points' to a disk record (for example). `Dereferencing' such a pointer (ex:
i=*p;) means ``seek to the location on disk where p `points' and return its
value''. Also statements like p->field=27; can store things on disk, etc. If
later on you find you can fit the entire pointed-to data structure in memory,
you just change the user-defined pseudo-pointer type and recompile. All the
code that used these `pseudo pointers' doesn't need to be changed at all.

INHERITANCE: We still have just scratched the surface. In fact, we haven't
even gotten to the `object-oriented' part yet! Suppose you have a Stack data
type with operations push, pop, etc. Suppose you want an InvertableStack,
which is `just like' Stack except it also has an `invert' operation. In `C'
style, you'd have to either (1) modify the existing Stack module (trouble if
`Stack' is being used by others), or (2) copy Stack into another file and text
edit that file (results in lots of code duplication, another chance to break
something tricky in the Stack part of InvertableStack, and especially twice as
much code to maintain). C++ provides a much cleaner solution: inheritance.
You say `InvertableStack inherits everything from Stack, and InvertableStack
adds the invert operation'. Done. Stack itself remains `closed' (untouched,
unmodified), and InvertableStack doesn't duplicate the code for push/pop/etc.

POLYMORPHISM: The real power of OOP isn't just inheritance, but is the ability
to pass an InvertableStack around as if it actually were a Stack. This is
`safe' since (in C++ at least) the is-a relation follows public inheritance
(ie: a InvertableStack is-a Stack that can also invert itself). Polymorphism
is easiest to understand from an example, so here's a `classic': a graphical
draw package might deal with Circles, Squares, Rectangles, general Polygons,
and Lines. All of these are Shapes. Most of the draw package's functions need
a `Shape' parameter (as opposed to some particular kind of shape like Square).
Ex: if a Shape is picked by a mouse, the Shape might get dragged across the
screen and placed into a new location. Polymorphism allows the code to work
correctly even if the compiler only knows that the parameter is a `Shape'
without knowing the exact kind of Shape it is. Furthermore suppose the
`pick_and_drag(Shape*) function just mentioned was compiled on Tuesday, and on
Wednesday you decide to add the Hexagon shape. Strange as it sounds,
pick_and_drag() will still work with Hexagons, even though the Hexagon didn't
even exist when pick_and_drag() was compiled!! (it's not really `amazing' once
you understand how the C++ compiler does it -- but it's still very convenient!)

==============================================================================

Q3: Who uses C++?
A: Lots and lots of companies and government sites. Lots.
Statistically, 20 to 30 people will consider themselves to be new C++
programmers before you finish reading the responses to these FAQs.

==============================================================================

Q4: Are there any C++ standardization efforts underway?
A: Yes; ANSI (American) and ISO (International) groups are working closely with
each other.

`X3J16' is the name of the ANSI-C++ committee.

`WG21' is the name of ISO's C++ standards group.

The committees are using the `ARM' as a base document:
`Annotated C++ Reference Manual', Ellis and Stroustrup, Addison/Wesley.
ISBN 0-201-51459-1

The major players in the ANSI/ISO C++ standards process includes just about
everyone:

AT&T, IBM, DEC, HP, Sun, MS, Borland, Zortech, Apple, OSF, here>, ... and a lot of users and smaller companies. About 70 people attend
each ANSI C++ meeting. People come from USA, UK, Japan, Germany, Sweden,
Denmark, France, ... (all have `local' committees sending official
representatives and conducting `local' meetings).

Optimistically the standard might be finished by 1995-6 time frame (this is
fast for a proper standards process).

==============================================================================

Q5: Where can I ftp a copy of the latest ANSI-C++ draft standard?
A: You can't. ANSI standards and/or drafts are NOT available in machine
readable form.

You can get a paper copy by sending a request to:
Standards Secretariat
CBEMA
311 First St NW, Suite 500
Washington, DC 20001
Ask for the latest version of `Working Paper for Draft Proposed American
National Standard for Information Systems -- Programming Language C++'.

==============================================================================

Q6: Is C++ backward compatible with ANSI-C?
A: Almost. C++ is as close as possible to compatible with ANSI-C but no closer.
In practice, the major difference is that C++ requires prototypes, and that
`f()' declares a function that takes no parameters, while ANSI-C rules state
that `f()' declares a function that takes any number of parameters of any type.
There are some very subtle differences as well, like the sizeof a char literal
being equal to the sizeof a char (in ANSI-C, sizeof('x') is the sizeof an int).
Structure `tags' are in the same namespace as other names in C++, but C++ has
some warts to take care of backward compatibility here.

==============================================================================

Q7: How long does it take to learn C++?
A: I and others teach standard industry `short courses' (for those not familiar
with these, you pack a university semester course into one 40hr work-week), and
have found them successful. However mastery takes experience, and there's no
substitute for time. Laboratory time is essential for any OOP course, since it
allows concepts to `gel'.

Generally people start out wondering why the company has devoted a full 5 days
to something as trivial as another programming language. Then about half way
through, they realize they're not being taught just a new syntax, but an
entirely different way of thinking and programming and designing and . . . .
Then they begin to feel dumb, since they can't quite grasp what is being said.
Then they get mad and wonder why the course isn't taught in two or three weeks
instead. Finally about Wednesday afternoon the lights go `clink', and their
faces brighten, and they `get it'. By Friday, they've had numerous laboratory
`experiments' and they've seen both sides of reusable components (both how to
code *from* reuse, and how to code *for* reuse). It's different in every time
I teach, but the `reuse' aspect is rewarding, since it has a large potential to
improve software production's overall economics.

It takes 9 months to `master' C++/OOP. Less if there is already a body of
experts and code that programmers have regular access to, more if there isn't a
`good' general purpose C++ class library available.

==============================================================================

**** PART 03 -- Basics of the paradigm ****

==============================================================================

Q8: 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'.

==============================================================================

Q9: 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).

==============================================================================

Q10: 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;
}

main()
{
int x, y;
//...
swap(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.

==============================================================================

Q11: 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.

==============================================================================

Q12: 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.

==============================================================================

Q13: 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 NULL pointer this special significance (references
should always alias *objects*, not a dereferenced NULL ptr).

==============================================================================

Q14: 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 {
public:
void f(int i, char c) { /*...*/ } //inline function within a class
};
or by defining the member function as `inline' outside the class:
class X {
public:
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
conventions).

==============================================================================

**** PART 04 -- Constructors and destructors ****

==============================================================================

Q15: What is a constructor? Why would I ever use one?
A: Objects should establish and maintain their own internal coherence. The
`maintaining' part is done by ensuring self-consistency is restored after any
operation completes (ex: by incrementing the link count after adding a new link
to a linked list). The part about `establishing coherence' is the job of a
constructor.

Constructors are like `init functions'; they build a valid object. The
constructor turns a pile of incoherent arbitrary bits into a living object.
Minimally it initializes any internally used fields that are needed, but it may
also allocate resources (memory, files, semaphores, sockets, ...).

A constructor is like a `factory': it builds objects from dust.

`ctor' is a typical abbreviation for constructor.

==============================================================================

Q16: How can I make a constructor call another constructor as a primitive?
A: You can't. Use an `init()' member function instead (often `private:').

==============================================================================

Q17: What are destructors really for? Why would I ever use them?
A: Destructors are used to release any resources allocated by the object's
constructor. Ex: a Lock class might lock a semaphore, and the destructor will
release that semaphore. The usual `resource' being acquired in a constructor
(and subsequently released in a destructor) is dynamically allocated memory.

`dtor' is a typical abbreviation for destructor

==============================================================================

**** PART 05 -- Operator overloading ****

==============================================================================

Q18: What is operator overloading?
A: Operator overloading allows the basic C/C++ operators to have user-defined
meanings on user-defined types (classes). They are syntactic sugar for
equivalent function calls; ex:

class X {
//...
public:
//...
};

X add(X, X); //a top-level function that adds two X's
X mul(X, X); //a top-level function that multiplies two X's

X f(X a, X b, X c)
{
return add(add(mul(a,b), mul(b,c)), mul(c,a));
}

Now merely replace `add' with `operator+' and `mul' with `operator*':

X operator+(X, X); //a top-level function that adds two X's
X operator*(X, X); //a top-level function that multiplies two X's

X f(X a, X b, X c)
{
return a*b + b*c + c*a;
}

==============================================================================

Q19: What operators can/cannot be overloaded?
A: Most can be overloaded. The only C operators that can't be are `.' and `?:'
(and `sizeof', which is technically an operator). C++ adds a few of its own
operators, most of which can be overloaded except `::' and `.*'.

Here's an example of the subscript operator (it returns a reference).
First withOUT operator overloading:
class Vec {
int data[100];
public:
int& elem(unsigned i) { if (i>99) error(); return data[i]; }
};

main()
{
Vec v;
v.elem(10) = 42;
v.elem(12) += v.elem(13);
}

Now simply replace `elem' with `operator[]':
class Vec {
int data[100];
public:
int& operator[](unsigned i) { if (i>99) error(); return data[i]; }
}; //^^^^^^^^^^--formerly `elem'

main()
{
Vec v;
v[10] = 42;
v[12] += v[13];
}

==============================================================================

Q20: Can I create a `**' operator for `to-the-power-of' operations?
A: No.

The names of, precedence of, associativity of, and arity of operators is fixed
by the language. There is no `**' operator in C++, so you cannot create one
for a class type.

If you doubt the wisdom of this approach, consider the following code:
x = y ** z;
Looks like your power operator? Nope. z may be a ptr, so this is actually:
x = y * (*z);
Lexical analysis groups characters into tokens at the lowest level of the
compiler's operations, so adding new operators would present an implementation
nightmare (not to mention the increased maintenance cost to read the code!).

Besides, operator overloading is just syntactic sugar for function calls. It
does not add fundamental power to the language (although this particular
syntactic sugar can be very sweet, it is not fundamentally necessary). I
suggest you overload `pow(base,exponent)', for which a double precision version
is provided by the ANSI-C library.

By the way: operator^ looks like a good candidate for to-the-power-of, but it
has neither the proper precedence nor associativity.

==============================================================================

**** PART 06 -- Friends ****

==============================================================================

Q21: What is a `friend'?
A: Friends can be either functions or other classes. The class grants friends
access privileges. Normally a developer has political and technical control
over both the class, its members, and its friends (that way you avoid political
problems when you want to update a portion, since you don't have to get
permission from the present owner of the other piece(s)).

==============================================================================

Q22: Do `friends' violate encapsulation?
A: Friends can be looked at three ways: (1) they are not class members and they
therefore violate encapsulation of the class members by their mere existence,
(2) a class' friends are absorbed into that class' encapsulation barrier, and
(3) any time anyone wants to do anything tricky they textedit the header file
and add a new friend so they can get right in there and fiddle 'dem bits.

No one argues that (3) is a Good Thing, and for good reasons. The arguments for
(1) always boil down to the rather arbitrary and somewhat naive view that a
class' member functions `should' be the *only* functions inside a class'
encapsulation barrier. I have not seen this view bear fruit by enhancing
software quality. On the other hand, I have seen (2) bear fruit by lowering
the *overall* coupling in a software system. Reason: friends can be used as
`liaisons' to provide safe, screened access for the whole world, perhaps in a
way that the class syntactically or semantically isn't able to do for itself.

Conclusion: friend functions are merely a syntactic variant of a class' public
access functions. When used in this manner, they don't violate encapsulation
any more than a member function violates encapsulation. Thus a class' friends
and members *are* the encapsulation barrier, as defined by the class itself.

I've actually seen the `friends always violate encapsulation' view *destroy*
encapsulation: programmers who have been taught that friends are inherently

evil want to avoid them, but they have another class or fn that needs access to
some internal detail in the class, so they provide a member fn which exposes
the class' internal details to the PUBLIC! Private decisions should stay
private, and only those inside your encapsulation barrier (your members,
friends, and [for `protected' things] your subclasses) should have access.

==============================================================================

Q23: What are some advantages/disadvantages of using friends?
A: The advantage of using friends is generally syntactic. Ie: both a member fn
and a friend are equally privileged (100% vested), but a friend function can be
called like f(obj), where a member is called like obj.f(). When it's not for
syntactic reasons (which is not a `bad' reason -- making an abstraction's
syntax more readable lowers maintenance costs!), friends are used when two or
more classes are designed to be more tightly coupled than you want for `joe
public' (ex: you want to allow class `ListIter' to have more privilege with
class `List' than you want to give to `main()').

Friends have three disadvantages. The first disadvantage is that they add to
the global namespace. In contrast, the namespace of member functions is buried
within the class, reducing the chance for namespace collisions for functions.

The second disadvantage is that they aren't inherited. That is, the
`friendship privilege' isn't inherited. This is actually an advantage when it
comes to encapsulation. Ex: I may declare you as my friend, but that doesn't
mean I trust your kids.

The third disadvantage is that they don't bind dynamically. Ie: they don't
respond to polymorphism. There are no virtual friends; if you need one, have a
friend call a hidden (usually `protected:') virtual member fn. Friends that
take a ptr/ref to a class can also take a ptr/ref to a publically derived class
object, so they act as if they are inherited, but the friendship *rights* are
not inherited (the friend of a base has no special access to a class derived
from that base).

==============================================================================

Q24: What does it mean that `friendship is neither inherited nor transitive'?
A: This is speaking of the access privileges granted when a class declares a
friend.

The access privilege of friendship is not inherited:
* I may trust you, but I don't necessarily trust your kids.
* My friends aren't necessarily friends of my kids.
* Class `Base' declares f() to be a friend, but f() has no special access
rights with class `Derived'.

The access privilege of friendship is not transitive:
* I may trust you, and you may trust Sam, but that doesn't necessarily mean
that I trust Sam.
* A friend of a friend is not necessarily a friend.

==============================================================================

Q25: When would I use a member function as opposed to a friend function?
A: Use a member when you can, and a friend when you have to.

Like in real life, my family members have certain privileges that my friends do
not have (ex: my family members inherit from me, but my friends do not, etc).
To grant privileged access to a function, you need either a friend or a member;
there is no additional loss of encapsulation one way or the other. Sometimes
friends are syntactically better (ex: in class `X', friend fns allow the `X'
param to be second, while members require it to be first). Another good use of
friend functions are the binary infix arithmetic operators. Ex: `aComplex +
aComplex' probably should be defined as a friend rather than a member, since
you want to allow `aFloat + aComplex' as well (members don't allow promotion of
the left hand arg, since that would change the class of the object that is the
recipient of the message).

==============================================================================

--
Marshall Cline
--
Marshall P. Cline, Ph.D. / Paradigm Shift, Inc / One Park St/Norwood, NY 13668
[email protected] / 315-353-6100 / FAX: 315-353-6110


  3 Responses to “Category : C++ Source Code
Archive   : CPPFAQ93.ZIP
Filename : CPP-FAQ.1

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/