From: cline@sun.soe.clarkson.edu (Marshall Cline)
Newsgroups: comp.lang.c++
Subject: C++ FAQ: posting #1/4
Date: 14 Nov 1994 00:26:13 GMT
Organization: Paradigm Shift, Inc (training/consulting/OOD/OOP/C++)
Message-ID: <3a6ar5$gd6@library.erc.clarkson.edu>
Reply-To: cline@parashift.com (Marshall Cline)
	DOCUMENT:	Frequently-Asked-Questions for comp.lang.c++
	DOCUMENT:	Frequently-Asked-Questions for comp.lang.c++
	REVISION:	Nov 13, 1994

	POSTING!=BOOK:	This C++ FAQ posting is NOT the same as the "FAQ book".
			The "FAQ book" ("C++ FAQs", Addison-Wesley, 1995) is
			5x larger than this posting.  See below for more.

	AUTHOR:		Marshall P. Cline, Ph.D.
			Paradigm Shift, Inc.
			One Park St. / Norwood, NY  13668
			voice: 315-353-6100
			fax:   315-353-6110
			email: cline@parashift.com

	COPYRIGHT:	Copyright (C), 1991-94 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 a nominal copy fee may be charged),
			and provided that the AUTHOR, COPYRIGHT, & NO WARRANTY
			sections are retained verbatim and 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
			URL:  ftp://sun.soe.clarkson.edu/pub/C++/FAQ

	WITHOUT FTP:	You can also get it by sending electronic mail:
			|	To: archive-server@sun.soe.clarkson.edu
			|	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 FAQ appears every month in that newsgroup,
			and is maintained by Steve Summit (scs@eskimo.com).

==============================================================================
SUBSECTION 1A: "FAQ book" versus "FAQ posting"
==============================================================================

Now that Addison-Wesley has published "C++ FAQs" by Cline and Lomow (1995,
ISBN 0-201-58958-3), many people have asked about the relationship between the
book and this posting.  Some who haven't seen the book have wondered whether
the posting was equivalent to the book.  This section answers these questions.

The "FAQ book" (at bookstores starting Oct. 94) is loosely based on the same
concepts as this posting.  However the FAQ book is approx five (5) times
bigger than this posting, including thousands of cross references, external
references, and index terms, as well as many programming examples.

==============================================================================
SUBSECTION 1B: Table of Contents
==============================================================================

========== POSTING #1 ==========

SECTION 1: Introduction and table of contents
SUBSECTION 1A: "FAQ book" versus "FAQ posting"
SUBSECTION 1B: Table of Contents
SUBSECTION 1C: Nomenclature and Common Abbreviations

SECTION 2: How should I post something? (READ BEFORE POSTING)
Q1: Which newsgroup should I post my questions?
Q2: How do I post a question about code that doesn't work correctly?

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

SECTION 4: Basics of the paradigm
Q10: What is a class?
Q11: What is an object?
Q12: What is a reference?
Q13: What happens if you assign to a reference?
Q14: How can you reseat a reference to make it refer to a different object?
Q15: When should I use references, and when should I use pointers?
Q16: What's the deal with inline functions?

SECTION 5: Constructors and destructors
Q17: What's the deal with constructors?
Q18: How can I make a constructor call another constructor as a primitive?
Q19: What's the deal with destructors?

SECTION 6: Operator overloading
Q20: What's the deal with operator overloading?
Q21: What operators can/cannot be overloaded?
Q22: Can I create a "**" operator for "to-the-power-of" operations?

SECTION 7: Friends
Q23: What is a "friend"?
Q24: Do "friends" violate encapsulation?
Q25: What are some advantages/disadvantages of using friend functions?
Q26: What does it mean that "friendship is neither inherited nor transitive"?
Q27: Should my class declare a member function or a friend function?

SECTION 8: Input/output via <iostream.h> and <stdio.h>
Q28: How can I provide printing for a "class Fred"?
Q29: Why should I use <iostream.h> instead of the traditional <stdio.h>?

========== POSTING #2 ==========

SECTION 9: Freestore management
Q30: Does "delete p" delete the pointer "p", or the pointed-to-data, "*p"?
Q31: Can I "free()" pointers allocated with "new"?  Can I "delete" pointers
   alloc'd with "malloc()"?
Q32: Why should I use "new" instead of trustworthy old malloc()?
Q33: Why doesn't C++ have a "realloc()" along with "new" and "delete"?
Q34: How do I allocate / unallocate an array of things?
Q35: What if I forget the "[]" when "delete"ing array allocated via "new
   Fred[n]"?

SECTION 10: Debugging and error handling
Q36: How can I handle a constructor that fails?
Q37: How should I handle resources if my constructors may throw exceptions?

SECTION 11: Const correctness
Q38: What is "const correctness"?
Q39: Should I try to get things const correct "sooner" or "later"?
Q40: What is a "const member function"?
Q41: What do I do if I want to update an "invisible" data member inside a
   "const" member function?
Q42: Does "const_cast" mean lost optimization opportunities?

SECTION 12: Inheritance
Q43: Is inheritance important to C++?
Q44: When would I use inheritance?
Q45: How do you express inheritance in C++?
Q46: Is it ok to convert a pointer from a derived class to its base class?
Q47: Derived* --> Base* works ok; why doesn't Derived** --> Base** work?
Q48: Does array-of-Derived is-NOT-a-kind-of array-of-Base mean arrays are
   bad?
SUBSECTION 12A: Inheritance -- Virtual functions
Q49: What is a "virtual member function"?
Q50: How can C++ achieve dynamic binding yet also static typing?
Q51: Should a derived class replace ("override") a non-virtual fn from a base
   class?
Q52: What's the meaning of, "Warning: Derived::f(int) hides Base::f(float)"?
SUBSECTION 12B: Inheritance -- Conformance
Q53: Should I hide public member fns inherited from my base class?
Q54: Is a "Circle" a kind-of an "Ellipse"?
Q55: Are there other options to the "Circle is/isnot kind-of Ellipse"
   dilemma?
SUBSECTION 12C: Inheritance -- Access rules
Q56: Why can't my derived class access "private" things from my base class?
Q57: What's the difference between "public:", "private:", and "protected:"?
Q58: How can I protect subclasses from breaking when I change internal parts?
SUBSECTION 12D: Inheritance -- Constructors and destructors
Q59: When my base class's constructor calls a virtual function, why doesn't my
   derived class's override of that virtual function get invoked?
Q60: Does a derived class destructor need to explicitly call the base
   destructor?
SUBSECTION 12E: Inheritance -- Private and protected inheritance
Q61: How do you express "private inheritance"?
Q62: How are "private inheritance" and "composition" similar?
Q63: Which should I prefer: composition or private inheritance?
Q64: Should I pointer-cast from a "privately" derived class to its base
   class?
Q65: How is protected inheritance related to private inheritance?
Q66: What are the access rules with "private" and "protected" inheritance?

SECTION 13: Abstraction
Q67: What's the big deal of separating interface from implementation?
Q68: How do I separate interface from implementation in C++ (like Modula-2)?
Q69: What is an ABC ("abstract base class")?
Q70: What is a "pure virtual" member function?
Q71: How can I provide printing for an entire hierarchy of classes?
Q72: When should my destructor be virtual?
Q73: What is a "virtual constructor"?

========== POSTING #3 ==========

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

SECTION 15: Keys for Smalltalk programmers to learn C++
Q81: Why does C++'s FAQ have a section on Smalltalk? Is this
   Smalltalk-bashing?
Q82: What's the difference between C++ and Smalltalk?
Q83: What is "static typing", and how is it similar/dissimilar to Smalltalk?
Q84: Which is a better fit for C++: "static typing" or "dynamic typing"?
Q85: How can you tell if you have a dynamically typed C++ class library?
Q86: How do you use inheritance in C++, and is that different from Smalltalk?
Q87: What are the practical consequences of diffs in Smalltalk/C++
   inheritance?
Q88: Do you need to learn a "pure" OOPL before you learn C++?
Q89: What is the NIHCL?  Where can I get it?

SECTION 16: Reference and value semantics
Q90: What is value and/or reference semantics, and which is best in C++?
Q91: What is "virtual data," and how-can / why-would I use it in C++?
Q92: What's the difference between virtual data and dynamic data?
Q93: Should I normally use pointers to freestore allocated objects for my data
   members, or should I use "composition"?
Q94: What are relative costs of the 3 performance hits associated with
   allocating member objects from the freestore?
Q95: Are "inline virtual" member fns ever actually "inlined"?
Q96: Sounds like I should never use reference semantics, right?
Q97: Does the poor performance of ref semantics mean I should pass-by-value?

========== POSTING #4 ==========

SECTION 17: Linkage-to/relationship-with C
Q98: How can I call a C function "f(int,char,float)" from C++ code?
Q99: How can I create a C++ function "f(int,char,float)" that is callable by
   my C code?
Q100: Why's the linker giving errors for C/C++ fns being called from C++/C
   fns?
Q101: How can I pass an object of a C++ class to/from a C function?
Q102: Can my C function access data in an object of a C++ class?
Q103: Why do I feel like I'm "further from the machine" in C++ as opposed to
   C?

SECTION 18: Pointers to member functions
Q104: Is the type of "ptr-to-member-fn" different from "ptr-to-fn"?
Q105: How can I ensure objects of my class are always created via "new" rather
   than as locals or global/static objects?
Q106: How do I pass a ptr to member fn to a signal handler, X event callback,
   etc?
Q107: Why am I having trouble taking the address of a C++ function?
Q108: How do I declare an array of pointers to member functions?

SECTION 19: Container classes and templates
Q109: How can I insert/access/change elements from a linked
   list/hashtable/etc?
Q110: What's the idea behind "templates"?
Q111: What's the syntax / semantics for a "function template"?
Q112: What's the syntax / semantics for a "class template"?
Q113: What is a "parameterized type"?
Q114: What is "genericity"?

SECTION 20: Nuances of particular implementations
Q115: GNU C++ (g++) produces big executables for tiny programs; Why?
Q116: Is there a yacc-able C++ grammar?
Q117: What is C++ 1.2?  2.0?  2.1?  3.0?

SECTION 21: Miscellaneous technical and environmental issues
SUBSECTION 21A: Miscellaneous technical issues:
Q118: Why are classes with static data members getting linker errors?
Q119: What's the difference between the keywords struct and class?
Q120: Why can't I overload a function by its return type?
Q121: What is "persistence"?  What is a "persistent object"?
SUBSECTION 21B: Miscellaneous environmental issues:
Q122: Is there a TeX or LaTeX macro that fixes the spacing on "C++"?
Q123: Where can I access C++2LaTeX, a LaTeX pretty printer for C++ source?
Q124: Where can I access "tgrind," a pretty printer for C++/C/etc source?
Q125: Is there a C++-mode for GNU emacs?  If so, where can I get it?
Q126: Where can I get OS-specific FAQs answered (e.g.,BC++,DOS,Windows,etc)?
Q127: Why does my DOS C++ program says "Sorry: floating point code not
   linked"?
==============================================================================
SUBSECTION 1C: Nomenclature and Common Abbreviations
==============================================================================

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

    term	meaning
    ====	===========
    fn		function
    fns		functions
    param	parameter
    ptr		pointer, a C/C++ construct declared by:  int * p;
    ref		reference, a C++ construct declared by:  int & r;
    OO		object-oriented
    OOP		object-oriented programming
    OOPL	object-oriented programming language
    method	an alternate term for "member function"

==============================================================================
SECTION 2: How should I post something? (READ BEFORE POSTING)
==============================================================================

Q1: Which newsgroup should I post my questions?

Comp.lang.c++ is the best place to discuss the C++ language itself (e.g.,
C++ code design, syntax, style).  Other newsgroups exist for discussion of
topics which are specific to a particular system (e.g., MS Windows or UNIX)
or topics which are not directly related to the C++ language (e.g., how to
use your compiler).  Here's a list of some very active newsgroups and
excerpts from their Frequently Asked Questions lists.  These excerpts
should give you an idea of the type of topics frequently discussed there.

  comp.os.ms-windows.programmer.tools
     This group is intended for discussions about the selection and use of
     tools for Windows software development.
  comp.os.ms-windows.programmer.misc
     This group is for all other discussions about Windows software
     development.
  [There's one FAQ list for all the comp.os.ms-windows.programmer.* groups]
     FAQ 5.7.1.  Accessing C++ classes in a DLL
     FAQ 6.1.1.  A dialog as an MDI child window [with OWL]
     FAQ 6.2.1.  Disabled menu choices become enabled [with MFC]
     FAQ 8.1.5.  Using STRICT with windows.h
     FAQ 10.  A programmer's bibliography

  comp.os.msdos.programmer
     Much of the traffic is about language products (chiefly from Borland
     and Microsoft).
     FAQ 301. How can I read a character without [waiting for] the Enter key?
     FAQ 412. How can I read, create, change, or delete the volume label?
     FAQ 504. How do I configure a COM port and use it to transmit data?
     FAQ 602. How can a C program send control codes to my printer?
     FAQ 606. How can I find the Microsoft mouse position and button status?
     FAQ 707. How can I write a TSR (terminate-stay-resident) utility?
     FAQ B0. How can I contact [Borland, Microsoft]?
     [note: this FAQ is not available at rtfm.mit.edu; it is at Simtel
            (e.g., oak.oakland.edu) in /pub/msdos/info/faqp*.zip and Garbo
            (garbo.uwasa.fi) in /pc/doc-net/faqp*.zip]
  comp.os.msdos.programmer.turbovision [Borland's character-mode framework]

  comp.unix.programmer
     FAQ 4.5)  How do I use popen() to open a process for reading AND writing?
     FAQ 4.6)  How do I sleep() in a C program for less than one second?

  comp.unix.solaris (covers SunOS 4.x and Solaris)
     FAQ 4)  Signal Primer
     FAQ 5)  Waiting for Children to Exit

  gnu.g++.help
     FAQ: Where can I find a demangler?
     FAQ: Getting gcc/g++ binaries for Solaris 2.x
     FAQ: What documentation exists for g++ 2.x?
  gnu.g++.bug [bug reports for g++ -- see the g++ docs]

  comp.lang.c
     FAQ 1.10: I'm confused.  NULL is guaranteed to be 0, but the null
               pointer is not?
     FAQ 2.3:  So what is meant by the "equivalence of pointers and
               arrays" in C?
     FAQ 4.2:  [Why doesn't "printf("%d\n," i++ * i++);" work?]
     FAQ 7.1:  How can I write a function that takes a variable number
               of arguments? [stdarg.h or varargs.h]
     FAQ 10.4: How do I declare an array of pointers to functions returning
               pointers to functions returning pointers to characters?

Also check out the newsgroups comp.graphics, comp.sources.wanted,
comp.programming, and comp.object (its FAQ is an excellent introduction and
overview of OOP terms and concepts).  Remember that comp.std.c++ is for
discussion DIRECTLY related to the evolving ANSI/ISO C++ Standard (see more
below). 

There's rarely a need to crosspost a question to one of the above
newsgroups and comp.lang.c++ (readers in the system-specific newsgroups
aren't programming in machine language, ya know).  It's bad netiquette to
crosspost widely because your problem is "really important."  If you don't
get an answer in the "right" newsgroup and feel you must post here, at
least consider redirecting followups back to the appropriate newsgroup.

Before posting a question to any newsgroup you should read it's FAQ list.
An answer to your question is likely to be there, saving you the time of
posting and saving thousands of other people around the world the time of
reading your question.  People answering a FAQ are likely to be annoyed for
having to answer it for the umpteenth time, or they're likely to be giving
you a wrong or incomplete answer since they haven't read the FAQ either.

Frequently Asked Questions lists are available 24-hours a day via anonymous
ftp (rtfm.mit.edu in /pub/usenet/comp.what.ever) or e-mail server (send a
message with the line "help" to mail-server@rtfm.mit.edu).  See the article
"Introduction to the *.answers newsgroups" in the newsgroup news.answers or
news.announce.newusers (which contains many other must-read articles) for
more information.

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

Q2: How do I post a question about code that doesn't work correctly?

Here's some guidelines you should follow that will help people reading
comp.lang.c++ help you with an answer to your programming problem.

1. Please read the previous FAQ to make sure that your question is about the
   C++ language and not a question about programming on your system (e.g.,
   graphics, printers, devices, etc.) or using your compilation
   environment (e.g., "the IDE crashes when I...," "how do you turn off
   warnings about...," "how do I tell it to link my libraries").  If you
   want to know why your virtual CmOk() function isn't being called in
   your OWL program, your question is probably more appropriate in the
   Windows programming newsgroup.  If you can write a small stand-alone
   program which exhibits the same undesired compiler error or behavior
   as your OWL program, by all means post here in comp.lang.c++ since C++
   programmers using other systems could be of help.

2. Be descriptive in the subject line.  "C++ problem" leaves a lot to the
   imagination.  "Problem new'ing a multi-dimensional array" is good.
   Refrain from exclamation points, cries for HELPPP, and the once funny
   "SEX SEX SEX."  If you think the problem is specific to your compiler,
   you might want to mention the compiler/version in the subject line.

3. Post code that is complete and compilable.  It's extremely difficult
   to debug or reconstruct a program from a human language description.
   By "complete code" I mean that any types and functions used are
   declared, headers are #include'd, etc.  Please strip the code down to
   the bare essentials.  We don't need a program that does something
   useful at run-time, or even links.  We just need to be able to
   reproduce the undesired compiler error (possibly on a different
   compiler).  By "compilable code" I mean that it doesn't contain a
   bunch of uncommented ellipses or line numbers at the beginning of each
   line:

	14:	#include <iostream.h>
	15:	class Foo { ... };  // this is annoying

   Try to organize the code into one linear program instead of making us cut
   out and create header files.  Be very careful if you are typing the code
   into your article -- it's often difficult to tell whether something is a
   typo or the real cause of the problem.  Try using your editor's
   cut&paste or "insert file" feature instead.

4. Mention what compiler, compiler version, and system you're using.  I
   know, I just said that system-specific questions should go to a
   system-specific newsgroup, but compiler information is often very
   useful in diagnosing the problem: ("yeah, I remember Acme 1.2 having
   lots of problems in this area").  It also warns other users of that
   compiler about possible bugs.

5. Show us the exact compiler and linker options and libraries you used
   when building your program.

6. List the exact error message and where the error was given.  "Virtual
   functions don't work" doesn't tell us whether its a compile-, link-, or
   run-time problem.  If the problem is at run-time, give a good
   description of the behavior and any relevant information about your
   system setup.

7. Include a working e-mail address in your signature.  If the address in
   given your article's "From:" line is not correct, please notify your
   system administrator.  Until it is fixed, add a "Reply-To:" line to
   your headers that uses your correct e-mail address.

8. Please read the rest of this FAQ -- chances are your problem, or a
   closely related problem, is discussed here.  Thank you and I hope these
   suggestions help you find a solution to your problem.

==============================================================================
SECTION 3: Environmental/managerial issues
==============================================================================

Q3: What is OOP?  What is C++?

OO programming techniques are the best way we know of to develop large, complex
software applications and systems.

C++ is an OO programming language.  C++ can be used both as an OOPL and simply
"as a better C."  However if you use it "as a better C," don't expect to get
the benefits of object-oriented programming.

OO hype: the software industry is "failing" to meet demands for large, complex
software systems.  But this "failure" is actually due to our SUCCESSES: our
successes have propelled users to ask for more.  Unfortunately we created a
market hunger that the "structured" analysis, design and programming techniques
couldn't satisfy.  This required us to create a better paradigm.

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

Q4: What are some advantages of C++?

GROWTH OF C++: C++ is by far the most popular OOPL.  The number of C++ users is
doubling every 7.5 to 9 months.  Knowing C++ is a good resume-stuffer (but use
it as an OOPL rather than just as a better C).

ENCAPSULATION: Hiding our data structures allows us to change one chunk of a
system without breaking other chunks.  We provide our software chunks (we call
them "classes") with safe interfaces.  Users of a chunk use its interface only.
The relatively volatile "implementation" of this interface is "encapsulated"
("put into a capsule") to prevent users from becoming reliant on its temporary
decisions.  In simple C, this was done by making a module's data "static", thus
preventing another module from accessing our module's bits.

MULTIPLE INSTANCES: The typical C solution to encapsulation (see above) doesn't
support multiple instances of the data (it's hard to make multiple instances of
a module's "static" data).  If we needed multiple instances in C, we used a
"struct" (but this doesn't support "encapsulation").  In C++, we can have both
multiple instances and encapsulation via a "class": the "public" part of a
class contains the class's interface (normally these are a special kind of
function called a "member function"), and the "private" part of a class
contains the class's implementation (typically these are where the bits live).

INLINE FUNCTION CALLS: In straight C, you can achieve "encapsulated structs" by
putting a "void*" in a struct (the access functions use pointer casts).  This
forfeits type safety, and also imposes a function call to access even trivial
fields of the struct (if you allowed direct access to the struct's fields, the
underlying data structure would be difficult to change since too many chunks
would RELY on it being the "old" way).  Function call overhead is small, but
can add up.  C++ classes allow 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: C++ lets you overload the standard operators on a class,
which lets users exploit their intuition (e.g., "myString + yourString" might
do string concatenation, "myDate++" might increment the date, "z1 * z2" might
multiply complex numbers z1 and z2, "a[i]" might access the "i"th element of
the "linked list" called "a", etc.  You can even have "smart pointers" that
could "point" to a disk record or wherever ("x = *p" could "dereference" such a
pointer, which could seek to the location on disk where p "points" and return
its value").  This allows users to program in the language of the problem
domain rather than in the language of the machine.

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 AND DYNAMIC BINDING: 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 (i.e., a InvertableStack is-a Stack that can also invert itself).
Polymorphism and dynamic binding are 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).  E.g., if a Shape is picked by a mouse,
the Shape might get dragged across the screen and placed into a new location.
Polymorphism and dynamic binding allow 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!)

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

Q5: Who uses C++?

Lots and lots of companies and government sites.  Lots.

Statistically, 5 people became new C++ programmers while you read the words of
the previous FAQ.

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

Q6: Are there any C++ standardization efforts underway?

Yes; ANSI (American) and ISO (International) groups are working closely with
each other.  The ANSI-C++ committee is called "X3J16".  The ISO C++ standards
group is called "WG21".  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, etc ad nauseum.
About 70 people attend each meeting.  People come from USA, UK, Japan, Germany,
Sweden, Denmark, France, ... (all have "local" committees sending official
representatives and conducting "local" meetings).

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

Q7: Where can I get a copy of the latest ANSI-C++ draft standard?

ANSI standards and/or drafts are NOT available in machine readable form.  There
is NOT an "ftp" site that has a copy.  You can get a paper copy ($25) from:

	X3 Secretariat
	CBEMA
	1250 I Street NW
	Suite 200
	Washington, DC  20005
	202-626-5738

Ask for the latest version of "Working Paper for Draft Proposed American
National Standard for Information Systems -- Programming Language C++."

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

Q8: Is C++ backward compatible with ANSI-C?

Almost.

C++ is as close as possible to compatible with C, but no closer.  In practice,
the major difference is that C++ requires prototypes, and that "f()" declares a
function that takes no parameters (in C, "f()" is the same as "f(...)").  There
are some very subtle differences as well, like sizeof('x') is equal to
sizeof(char) in C++ but is equal to sizeof(int) in C.  Also, C++ puts structure
"tags" in the same namespace as other names, whereas C requires an explicit
"struct" (the "typedef struct Fred Fred" technique still works, but is
redundant in C++).

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

Q9: How long does it take to learn C++?

Companies like Paradigm Shift, Inc. successfully teach standard industry "short
courses", where we compress a university semester course into one 40hr work
week.  However true mastery takes experience; there's no substitute for time.
Hands-on projects are essential, since they allow concepts to "gel."

It takes 6-12 months to become proficient in C++/OOP.  Less if the developers
have easy access to a "local" body of experts, more if there isn't a "good"
general purpose C++ class library available.  To become one of these experts
who can mentor others takes around 3 years.

Some people never make it.  You don't have a chance unless you are teachable
and have personal drive.  As a bare minimum on "teachability," you have to be
able to admit when you've been wrong for years and years.  As a bare minimum on
"drive," you've got to be willing to put in some extra hours (changing the way
you think [a paradigm shift] is a LOT more painful than learning a few new
facts).

==============================================================================
SECTION 4: Basics of the paradigm
==============================================================================

Q10: What is a class?

The fundamental building block of OO software.

A class defines a data type, much like a struct would be in C.  In a computer
science sense, a type consists of both a set of states AND a set of operations
which transition between those states.  Thus "int" is a "type" because it has
both a set of states AND it has 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".

Think of "int" as a class that has methods called "operator++", etc.

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

Q11: What is an object?

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" usually means "an instance of a class."  Thus a class defines
the behavior of possibly many objects (instances).

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

Q12: What is a reference?

An alias (an alternate name) for an object.

References are frequently used for pass-by-reference:

	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.  In other
words, "i" IS "x" -- not a pointer to "x", nor a copy of "x", but "x" itself.
Anything you do to "i" gets done to "x", and vise versa.

Underneath it all, references are typically implemented by pointers.  The
effect is as if you used the C style pass-by-pointer, but the "&" is moved from
the caller into the callee, and you eliminate all the "*"s.

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

Q13: What happens if you assign to a reference?

You change the referrent (the object to which the reference refers).

Remember: the reference IS the referrent, so changing the reference changes the
referrent (a reference is an "Lvalue" [something that can appear on the
"L"eft-hand-side of an assignment statement] for the referrent).

This insight can be pushed a bit farther by allowing references to be RETURNED.
This allows function calls on the left hand side of an assignment statement,
which is useful with operator overloading.

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

Q14: How can you reseat a reference to make it refer to a different object?

No way.

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 (it has no
address; taking the address of a reference gives you the address of the
referrent; remember: the reference IS its referrent).

You can't separate the reference from the referent.

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

Q15: When should I use references, and when should I use pointers?

Use references when you can, and pointers when you have to.

References are usually preferred over ptrs whenever you don't need "reseating"
(see previous FAQ).  This usually means that references are most useful in a
class's public interface.  References 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).

NOTE: Old line C programmers sometimes don't like references since they provide
reference semantics that isn't explicit in the caller's code.  After some C++
experience, however, one quickly realizes this is a form of information hiding,
which is an asset rather than a liability.  E.g., programmers should write code
in the language of the problem rather than the language of the machine.

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

Q16: What's the deal with inline functions?

An inline function is a function whose code gets inserted into the caller's
code stream.  Like a macro, inline functions improve performance by avoiding
the overhead of the call itself and (especially!) by the compiler being able to
optimize THROUGH the call ("procedural integration").  Unlike macros, inline
functions avoid infamous macro errors by evaluating all arguments exactly once
(the "call" is semantically like a regular function call, only faster).  Also
unlike macros, argument types are checked, and necessary conversions are
performed correctly (macros are bad for your health; don't use them unless you
absolutely have to).

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) { /*...*/ }

or by including the function definition itself within a class:

	class Fred {
	public:
	  void f(int i, char c) { /*...*/ }
	};

or by defining the member function as "inline" outside the class:

	class Fred {
	public:
	  void f(int i, char c);
	};

	inline void Fred::f(int i, char c) { /*...*/ }

==============================================================================
SECTION 5: Constructors and destructors
==============================================================================

Q17: What's the deal with constructors?

Constructors build objects from dust.

Constructors are like "init functions"; they turn a pile of arbitrary bits into
a living object.  Minimally they initialize internally used fields.  They may
also allocate resources (memory, files, semaphores, sockets, etc).

"ctor" is a typical abbreviation for constructor.

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

Q18: How can I make a constructor call another constructor as a primitive?

No way.

Dragons be here: if you call another constructor, the compiler initializes a
temporary local object; it does NOT initialize "this" object.  You can combine
both constructors by using a default parameter, or you can share their common
code in a private "init()" member function.

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

Q19: What's the deal with destructors?

A destructor gives an object its last rites.

Destructors are used to release any resources allocated by the object.  E.g., a
Lock class might lock a semaphore, and the destructor will release that
semaphore.  The most common example is when the constructor uses "new", and the
destructor uses "delete".

Destructors are a "prepare to die" method.  They are often abbreviated "dtor".

==============================================================================
SECTION 6: Operator overloading
==============================================================================

Q20: What's the deal with operator overloading?

It allows users of your classes to use intuitive syntax.

Operator overloading allows C/C++ operators to have user-defined meanings on
user-defined types (classes).  They're syntactic sugar for function calls:

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

	#if 0
	  Fred add(Fred, Fred);		//without operator overloading
	  Fred mul(Fred, Fred);
	#else
	  Fred operator+(Fred, Fred);	//with operator overloading
	  Fred operator*(Fred, Fred);
	#endif

	Fred f(Fred a, Fred b, Fred c)
	{
	  #if 0
	    return add(add(mul(a,b), mul(b,c)), mul(c,a));  //without...
	  #else
	    return a*b + b*c + c*a;                         //with...
	  #endif
	}

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

Q21: What operators can/cannot be overloaded?

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 Array {
	public:
	  #if 0
	    int& elem(unsigned i) { if (i>99) error(); return data[i]; }
	  #else
	    int& operator[] (unsigned i) { if (i>99) error(); return data[i]; }
	  #endif
	private:
	  int data[100];
	};

	main()
	{
	  Array a;

	  #if 0
	    a.elem(10) = 42;
	    a.elem(12) += a.elem(13);
	  #else
	    a[10] = 42;
	    a[12] += a[13];
	  #endif
	}

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

Q22: Can I create a "**" operator for "to-the-power-of" operations?

Nope.

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're in doubt, consider that "x ** y" is the same as "x * (*y)" (in other
words, the compiler assumes "z" is a pointer).  Besides, operator overloading
is just syntactic sugar for function calls.  Although this particular syntactic
sugar can be very sweet, it doesn't add anything fundamental.  I suggest you
overload "pow(base,exponent)" (a double precision version is in <math.h>).

BTW: operator^ can work, except it has the wrong precedence and associativity.

==============================================================================
SECTION 7: Friends
==============================================================================

Q23: What is a "friend"?

Something to allow your class to grant access to another class or function.

Friends can be either functions or other classes.  A class grants access
privileges to its friends.  Normally a developer has political and technical
control over both the friends and methods of a class (else you need permission
from the owner of the other pieces when you want to update your class).

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

Q24: Do "friends" violate encapsulation?

If they're used properly, they actually ENHANCE encapsulation.

You often need to split a class in half when the two halves will have different
numbers of instances or different lifetimes.  In these cases, the two halves
usually need direct access to each other (the two halves USED to be in the same
class, so you haven't INCREASED the number of methods that have direct access
to a data structure; you've simply MOVED some of those methods).  The safest
way to implement this is to make the two halves friends of each other.

If you use friends like just described, you'll keep private things private.  In
a naive effort to avoid using friendship in situations like the above, many
people actually destroy encapsulation by either using public data (grotesque!),
or by making the data accessible between the halves via public get/set methods.
Having a public get and set method for a private datum is only ok when the
private datum "makes sense" from outside the class (from a user's perspective).
In many cases, these get/set methods are almost as bad as public data: they
hide (only) the NAMES of the private data members, but they don't hide the
existence of the private data members.

Similarly, if you use friend functions as a syntactic variant of a class's
public access functions, they don't violate encapsulation any more than a
member function violates encapsulation.  In other words, a class's friends and
members ARE the encapsulation barrier, as defined by the class itself.

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

Q25: What are some advantages/disadvantages of using friend functions?

They provide a degree of freedom in the interface design options.

Member fns and friend fns are equally privileged (100% vested).  The major
difference is that a friend function is called like "f(x)", while a member is
called like "x.f()".  Thus friend fns allow the class's designer to select
the syntax that is deemed most readable, which lowers maintenance costs.

The major disadvantage of friend functions is that they require an extra line
of code when you want dynamic binding.  To get the effect of a virtual friend,
the friend function should call a hidden (usually "protected:") virtual member
fn; e.g., "void f(Base& b) { b.do_f(); }".  Derived classes override the hidden
virtual member function ("void Derived::do_f()"), NOT the friend function.

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

Q26: What does it mean that "friendship is neither inherited nor transitive"?

The privileges of friendship aren't inherited: derived classes of a friend
aren't necessarily friends (I may declare you as my friend, but that doesn't
mean I necessarily trust your kids).  If class "Base" declares "f()" to be a
friend, "f()" doesn't have any automatic special access rights to the extra
stuff declared in derived class, "Derived."

The privileges of friendship aren't transitive: friends of a friend class
aren't necessarily friends of the original class (a friend of a friend isn't
necessarily a friend).  E.g., if class "Fred" declares class "Wilma" as a
friend, and class "Wilma" declares "f()" as a friend, "f()" doesn't necessarily
have any special access rights to "Fred".

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

Q27: Should my class declare a member function or a friend function?

Use a member when you can, and a friend when you have to.

Sometimes friends are syntactically better (e.g., in class "Fred", friend fns
allow the "Fred" param to be second, while members require it to be first).
Another good use of friend functions are the binary infix arithmetic operators
(e.g., "aComplex + aComplex" probably should be defined as a friend rather than
a member, since you want to allow "aFloat + aComplex" as well; recall 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 member function invocation).

In other cases, choose a member function over a friend function.

==============================================================================
SECTION 8: Input/output via <iostream.h> and <stdio.h>
==============================================================================

Q28: How can I provide printing for a "class Fred"?

Provide a friend operator<<:

	class Fred {
	public:
	  friend ostream& operator<< (ostream& o, const Fred& fred)
	    { return o << fred.i; }
	  //...
	private:
	  int i;    //just for illustration
	};

We use a friend rather than a member since the "Fred" parameter is second
rather than first.  Input is similar, but the signature is:

	istream& operator>> (istream& i, Fred& fred);
	                              // ^^^^^------- not "const Fred& fred"!

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

Q29: Why should I use <iostream.h> instead of the traditional <stdio.h>?

Increase type safety, reduce errors, improve performance, allow extensibility,
and provide subclassability.

Printf is arguably not broken, and scanf is perhaps livable despite being error
prone, however both are limited with respect to what C++ I/O can do.  C++ I/O
(using "<<" and ">>") is, relative to C (using "printf()" and "scanf()"):

 * Type safe -- type of object being I/O'd is known statically by the compiler,
   rather than via dynamically tested via "%" fields.

 * Less error prone -- redundant info increases the chance of errors.  C++ I/O
   has no redundant "%" tokens to get right.

 * Faster -- printf is an "interpreter" of a tiny language whose constructs
   mainly include "%" fields; it uses these fields to select the right
   formatting primitive at run-time.  C++ I/O picks these routines statically
   based on actual types of the args.  This improves performance.

 * Extensible -- the C++ I/O mechanism allows new user-defined types to be
   added without breaking existing code (imagine the chaos if everyone was
   simultaneously adding new incompatible "%" fields to printf and scanf?!).

 * Subclassable -- ostream and istream (the C++ replacements for FILE*) are
   real classes, and hence subclassable.  This means you can have other user
   defined things that look and act like streams, yet that do whatever strange
   and wonderful things you want.  You automatically get to use the zillions of
   lines of I/O code written by users you don't even know, and they don't need
   to know about your "extended stream" class.

--
Marshall Cline
--
Marshall P. Cline, Ph.D. / Paradigm Shift Inc / PO Box 5108 / Potsdam NY 13676
cline@sun.soe.clarkson.edu / 315-353-6100 / FAX: 315-353-6110

From ankh.iia.org!uunet!news.mathworks.com!news.kei.com!ub!library.erc.clarkson.edu!sun.soe.clarkson.edu!cline Sun Dec 18 23:53:21 1994
Path: ankh.iia.org!uunet!news.mathworks.com!news.kei.com!ub!library.erc.clarkson.edu!sun.soe.clarkson.edu!cline
From: cline@sun.soe.clarkson.edu (Marshall Cline)
Newsgroups: comp.lang.c++
Subject: C++ FAQ: posting #1/4
Followup-To: comp.lang.c++
Date: 13 Dec 1994 05:57:31 GMT
Organization: Paradigm Shift, Inc (training/consulting/OOD/OOP/C++)
Lines: 1078
Sender: cline@sun.soe.clarkson.edu
Distribution: world
Expires: +1 month
Message-ID: <3cjd4b$gkd@library.erc.clarkson.edu>
Reply-To: cline@parashift.com (Marshall Cline)
NNTP-Posting-Host: sun.soe.clarkson.edu
Summary: Please read this before posting to comp.lang.c++

comp.lang.c++ Frequently Asked Questions list (with answers, fortunately).
Copyright (C) 1991-94 Marshall P. Cline, Ph.D.
Posting 1 of 4.

UPDATED 12/94:
 * Added a FAQ on STL (currently #115).
 * Added a FAQ on name mangling (currently #119).
 * Fixed typo in FAQ that compared composition with private inheritance.
 * Corrected some spelling errors.

UPDATED 11/94:
 * Added differentiator between "FAQ book" and "FAQ posting"
 * Other cosmetic changes

UPDATED 10/94:
 * Fixed a few typos

UPDATED 9/94:
 * Minor cosmetic changes

UPDATED 8/94:
 * Made it up-to-date with respect to "typeid" and "dynamic_cast".
 * Made it up-to-date with respect to "mutable" and "const_cast".
 * Rewrote most of the answers to provide general cleanup.
 * The quotation marks are now "..." rather than `...' or ``...''
 * Sample code lines start with a tab; no other lines starts with a tab.
 * Everything was edited; minor modifications everywhere.

==============================================================================
SECTION 1: Introduction and table of contents
==============================================================================

	DOCUMENT:	Frequently-Asked-Questions for comp.lang.c++
	REVISION:	Dec 12, 1994

	POSTING!=BOOK:	This C++ FAQ posting is NOT the same as the "FAQ book".
			The "FAQ book" ("C++ FAQs", Addison-Wesley, 1995) is
			5x larger than this posting.  See below for more.

	AUTHOR:		Marshall P. Cline, Ph.D.
			Paradigm Shift, Inc.
			One Park St. / Norwood, NY  13668
			voice: 315-353-6100
			fax:   315-353-6110
			email: cline@parashift.com

	COPYRIGHT:	Copyright (C), 1991-94 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 a nominal copy fee may be charged),
			and provided that the AUTHOR, COPYRIGHT, & NO WARRANTY
			sections are retained verbatim and 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
			URL:  ftp://sun.soe.clarkson.edu/pub/C++/FAQ

	WITHOUT FTP:	You can also get it by sending electronic mail:
			|	To: archive-server@sun.soe.clarkson.edu
			|	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 FAQ appears every month in that newsgroup,
			and is maintained by Steve Summit (scs@eskimo.com).

==============================================================================
SUBSECTION 1A: "FAQ book" versus "FAQ posting"
==============================================================================

Now that Addison-Wesley has published "C++ FAQs" by Cline and Lomow (1995,
ISBN 0-201-58958-3), many people have asked about the relationship between the
book and this posting.  Some who haven't seen the book have wondered whether
the posting was equivalent to the book.  This section answers these questions.

The "FAQ book" (at bookstores starting Oct. 94) is loosely based on the same
concepts as this posting.  However the FAQ book is approx five (5) times
bigger than this posting, including thousands of cross references, external
references, and index terms, as well as many programming examples.

==============================================================================
SUBSECTION 1B: Table of Contents
==============================================================================

========== POSTING #1 ==========

SECTION 1: Introduction and table of contents
SUBSECTION 1A: "FAQ book" versus "FAQ posting"
SUBSECTION 1B: Table of Contents
SUBSECTION 1C: Nomenclature and Common Abbreviations

SECTION 2: How should I post something? (READ BEFORE POSTING)
Q1: Which newsgroup should I post my questions?
Q2: How do I post a question about code that doesn't work correctly?

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

SECTION 4: Basics of the paradigm
Q10: What is a class?
Q11: What is an object?
Q12: What is a reference?
Q13: What happens if you assign to a reference?
Q14: How can you reseat a reference to make it refer to a different object?
Q15: When should I use references, and when should I use pointers?
Q16: What's the deal with inline functions?

SECTION 5: Constructors and destructors
Q17: What's the deal with constructors?
Q18: How can I make a constructor call another constructor as a primitive?
Q19: What's the deal with destructors?

SECTION 6: Operator overloading
Q20: What's the deal with operator overloading?
Q21: What operators can/cannot be overloaded?
Q22: Can I create a "**" operator for "to-the-power-of" operations?

SECTION 7: Friends
Q23: What is a "friend"?
Q24: Do "friends" violate encapsulation?
Q25: What are some advantages/disadvantages of using friend functions?
Q26: What does it mean that "friendship is neither inherited nor transitive"?
Q27: Should my class declare a member function or a friend function?

SECTION 8: Input/output via <iostream.h> and <stdio.h>
Q28: How can I provide printing for a "class Fred"?
Q29: Why should I use <iostream.h> instead of the traditional <stdio.h>?

========== POSTING #2 ==========

SECTION 9: Freestore management
Q30: Does "delete p" delete the pointer "p", or the pointed-to-data, "*p"?
Q31: Can I "free()" pointers allocated with "new"?  Can I "delete" pointers
   alloc'd with "malloc()"?
Q32: Why should I use "new" instead of trustworthy old malloc()?
Q33: Why doesn't C++ have a "realloc()" along with "new" and "delete"?
Q34: How do I allocate / unallocate an array of things?
Q35: What if I forget the "[]" when "delete"ing array allocated via "new
   Fred[n]"?

SECTION 10: Debugging and error handling
Q36: How can I handle a constructor that fails?
Q37: How should I handle resources if my constructors may throw exceptions?

SECTION 11: Const correctness
Q38: What is "const correctness"?
Q39: Should I try to get things const correct "sooner" or "later"?
Q40: What is a "const member function"?
Q41: What do I do if I want to update an "invisible" data member inside a
   "const" member function?
Q42: Does "const_cast" mean lost optimization opportunities?

SECTION 12: Inheritance
Q43: Is inheritance important to C++?
Q44: When would I use inheritance?
Q45: How do you express inheritance in C++?
Q46: Is it ok to convert a pointer from a derived class to its base class?
Q47: Derived* --> Base* works ok; why doesn't Derived** --> Base** work?
Q48: Does array-of-Derived is-NOT-a-kind-of array-of-Base mean arrays are
   bad?
SUBSECTION 12A: Inheritance -- Virtual functions
Q49: What is a "virtual member function"?
Q50: How can C++ achieve dynamic binding yet also static typing?
Q51: Should a derived class replace ("override") a non-virtual fn from a base
   class?
Q52: What's the meaning of, "Warning: Derived::f(int) hides Base::f(float)"?
SUBSECTION 12B: Inheritance -- Conformance
Q53: Should I hide public member fns inherited from my base class?
Q54: Is a "Circle" a kind-of an "Ellipse"?
Q55: Are there other options to the "Circle is/isnot kind-of Ellipse"
   dilemma?
SUBSECTION 12C: Inheritance -- Access rules
Q56: Why can't my derived class access "private" things from my base class?
Q57: What's the difference between "public:", "private:", and "protected:"?
Q58: How can I protect subclasses from breaking when I change internal parts?
SUBSECTION 12D: Inheritance -- Constructors and destructors
Q59: When my base class's constructor calls a virtual function, why doesn't my
   derived class's override of that virtual function get invoked?
Q60: Does a derived class destructor need to explicitly call the base
   destructor?
SUBSECTION 12E: Inheritance -- Private and protected inheritance
Q61: How do you express "private inheritance"?
Q62: How are "private inheritance" and "composition" similar?
Q63: Which should I prefer: composition or private inheritance?
Q64: Should I pointer-cast from a "privately" derived class to its base
   class?
Q65: How is protected inheritance related to private inheritance?
Q66: What are the access rules with "private" and "protected" inheritance?

SECTION 13: Abstraction
Q67: What's the big deal of separating interface from implementation?
Q68: How do I separate interface from implementation in C++ (like Modula-2)?
Q69: What is an ABC ("abstract base class")?
Q70: What is a "pure virtual" member function?
Q71: How can I provide printing for an entire hierarchy of classes?
Q72: When should my destructor be virtual?
Q73: What is a "virtual constructor"?

========== POSTING #3 ==========

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

SECTION 15: Keys for Smalltalk programmers to learn C++
Q81: Why does C++'s FAQ have a section on Smalltalk? Is this
   Smalltalk-bashing?
Q82: What's the difference between C++ and Smalltalk?
Q83: What is "static typing", and how is it similar/dissimilar to Smalltalk?
Q84: Which is a better fit for C++: "static typing" or "dynamic typing"?
Q85: How can you tell if you have a dynamically typed C++ class library?
Q86: How do you use inheritance in C++, and is that different from Smalltalk?
Q87: What are the practical consequences of diffs in Smalltalk/C++
   inheritance?
Q88: Do you need to learn a "pure" OOPL before you learn C++?
Q89: What is the NIHCL?  Where can I get it?

SECTION 16: Reference and value semantics
Q90: What is value and/or reference semantics, and which is best in C++?
Q91: What is "virtual data," and how-can / why-would I use it in C++?
Q92: What's the difference between virtual data and dynamic data?
Q93: Should I normally use pointers to freestore allocated objects for my data
   members, or should I use "composition"?
Q94: What are relative costs of the 3 performance hits associated with
   allocating member objects from the freestore?
Q95: Are "inline virtual" member fns ever actually "inlined"?
Q96: Sounds like I should never use reference semantics, right?
Q97: Does the poor performance of ref semantics mean I should pass-by-value?

========== POSTING #4 ==========

SECTION 17: Linkage-to/relationship-with C
Q98: How can I call a C function "f(int,char,float)" from C++ code?
Q99: How can I create a C++ function "f(int,char,float)" that is callable by
   my C code?
Q100: Why's the linker giving errors for C/C++ fns being called from C++/C
   fns?
Q101: How can I pass an object of a C++ class to/from a C function?
Q102: Can my C function access data in an object of a C++ class?
Q103: Why do I feel like I'm "further from the machine" in C++ as opposed to
   C?

SECTION 18: Pointers to member functions
Q104: Is the type of "ptr-to-member-fn" different from "ptr-to-fn"?
Q105: How can I ensure objects of my class are always created via "new" rather
   than as locals or global/static objects?
Q106: How do I pass a ptr to member fn to a signal handler, X event callback,
   etc?
Q107: Why am I having trouble taking the address of a C++ function?
Q108: How do I declare an array of pointers to member functions?

SECTION 19: Container classes and templates
Q109: How can I insert/access/change elements from a linked
   list/hashtable/etc?
Q110: What's the idea behind "templates"?
Q111: What's the syntax / semantics for a "function template"?
Q112: What's the syntax / semantics for a "class template"?
Q113: What is a "parameterized type"?
Q114: What is "genericity"?
Q115: Where can I get a copy of "STL"?

SECTION 20: Nuances of particular implementations
Q116: GNU C++ (g++) produces big executables for tiny programs; Why?
Q117: Is there a yacc-able C++ grammar?
Q118: What is C++ 1.2?  2.0?  2.1?  3.0?
Q119: If name mangling was standardized, could I link code compiled with
   compilers from different compiler vendors?

SECTION 21: Miscellaneous technical and environmental issues
SUBSECTION 21A: Miscellaneous technical issues:
Q120: Why are classes with static data members getting linker errors?
Q121: What's the difference between the keywords struct and class?
Q122: Why can't I overload a function by its return type?
Q123: What is "persistence"?  What is a "persistent object"?
SUBSECTION 21B: Miscellaneous environmental issues:
Q124: Is there a TeX or LaTeX macro that fixes the spacing on "C++"?
Q125: Where can I access C++2LaTeX, a LaTeX pretty printer for C++ source?
Q126: Where can I access "tgrind," a pretty printer for C++/C/etc source?
Q127: Is there a C++-mode for GNU emacs?  If so, where can I get it?
Q128: Where can I get OS-specific FAQs answered (e.g.,BC++,DOS,Windows,etc)?
Q129: Why does my DOS C++ program says "Sorry: floating point code not
   linked"?
==============================================================================
SUBSECTION 1C: Nomenclature and Common Abbreviations
==============================================================================

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

    term	meaning
    ====	===========
    fn		function
    fns		functions
    param	parameter
    ptr		pointer, a C/C++ construct declared by:  int * p;
    ref		reference, a C++ construct declared by:  int & r;
    OO		object-oriented
    OOP		object-oriented programming
    OOPL	object-oriented programming language
    method	an alternate term for "member function"

==============================================================================
SECTION 2: How should I post something? (READ BEFORE POSTING)
==============================================================================

Q1: Which newsgroup should I post my questions?

Comp.lang.c++ is the best place to discuss the C++ language itself (e.g.,
C++ code design, syntax, style).  Other newsgroups exist for discussion of
topics which are specific to a particular system (e.g., MS Windows or UNIX)
or topics which are not directly related to the C++ language (e.g., how to
use your compiler).  Here's a list of some very active newsgroups and
excerpts from their Frequently Asked Questions lists.  These excerpts
should give you an idea of the type of topics frequently discussed there.

  comp.os.ms-windows.programmer.tools
     This group is intended for discussions about the selection and use of
     tools for Windows software development.
  comp.os.ms-windows.programmer.misc
     This group is for all other discussions about Windows software
     development.
  [There's one FAQ list for all the comp.os.ms-windows.programmer.* groups]
     FAQ 5.7.1.  Accessing C++ classes in a DLL
     FAQ 6.1.1.  A dialog as an MDI child window [with OWL]
     FAQ 6.2.1.  Disabled menu choices become enabled [with MFC]
     FAQ 8.1.5.  Using STRICT with windows.h
     FAQ 10.  A programmer's bibliography

  comp.os.msdos.programmer
     Much of the traffic is about language products (chiefly from Borland
     and Microsoft).
     FAQ 301. How can I read a character without [waiting for] the Enter key?
     FAQ 412. How can I read, create, change, or delete the volume label?
     FAQ 504. How do I configure a COM port and use it to transmit data?
     FAQ 602. How can a C program send control codes to my printer?
     FAQ 606. How can I find the Microsoft mouse position and button status?
     FAQ 707. How can I write a TSR (terminate-stay-resident) utility?
     FAQ B0. How can I contact [Borland, Microsoft]?
     [note: this FAQ is not available at rtfm.mit.edu; it is at Simtel
            (e.g., oak.oakland.edu) in /pub/msdos/info/faqp*.zip and Garbo
            (garbo.uwasa.fi) in /pc/doc-net/faqp*.zip]
  comp.os.msdos.programmer.turbovision [Borland's character-mode framework]

  comp.unix.programmer
     FAQ 4.5)  How do I use popen() to open a process for reading AND writing?
     FAQ 4.6)  How do I sleep() in a C program for less than one second?

  comp.unix.solaris (covers SunOS 4.x and Solaris)
     FAQ 4)  Signal Primer
     FAQ 5)  Waiting for Children to Exit

  gnu.g++.help
     FAQ: Where can I find a demangler?
     FAQ: Getting gcc/g++ binaries for Solaris 2.x
     FAQ: What documentation exists for g++ 2.x?
  gnu.g++.bug [bug reports for g++ -- see the g++ docs]

  comp.lang.c
     FAQ 1.10: I'm confused.  NULL is guaranteed to be 0, but the null
               pointer is not?
     FAQ 2.3:  So what is meant by the "equivalence of pointers and
               arrays" in C?
     FAQ 4.2:  [Why doesn't "printf("%d\n," i++ * i++);" work?]
     FAQ 7.1:  How can I write a function that takes a variable number
               of arguments? [stdarg.h or varargs.h]
     FAQ 10.4: How do I declare an array of pointers to functions returning
               pointers to functions returning pointers to characters?

Also check out the newsgroups comp.graphics, comp.sources.wanted,
comp.programming, and comp.object (its FAQ is an excellent introduction and
overview of OOP terms and concepts).  Remember that comp.std.c++ is for
discussion DIRECTLY related to the evolving ANSI/ISO C++ Standard (see more
below). 

There's rarely a need to crosspost a question to one of the above
newsgroups and comp.lang.c++ (readers in the system-specific newsgroups
aren't programming in machine language, ya know).  It's bad netiquette to
crosspost widely because your problem is "really important."  If you don't
get an answer in the "right" newsgroup and feel you must post here, at
least consider redirecting followups back to the appropriate newsgroup.

Before posting a question to any newsgroup you should read it's FAQ list.
An answer to your question is likely to be there, saving you the time of
posting and saving thousands of other people around the world the time of
reading your question.  People answering a FAQ are likely to be annoyed for
having to answer it for the umpteenth time, or they're likely to be giving
you a wrong or incomplete answer since they haven't read the FAQ either.

Frequently Asked Questions lists are available 24-hours a day via anonymous
ftp (rtfm.mit.edu in /pub/usenet/comp.what.ever) or e-mail server (send a
message with the line "help" to mail-server@rtfm.mit.edu).  See the article
"Introduction to the *.answers newsgroups" in the newsgroup news.answers or
news.announce.newusers (which contains many other must-read articles) for
more information.

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

Q2: How do I post a question about code that doesn't work correctly?

Here's some guidelines you should follow that will help people reading
comp.lang.c++ help you with an answer to your programming problem.

1. Please read the previous FAQ to make sure that your question is about the
   C++ language and not a question about programming on your system (e.g.,
   graphics, printers, devices, etc.) or using your compilation
   environment (e.g., "the IDE crashes when I...," "how do you turn off
   warnings about...," "how do I tell it to link my libraries").  If you
   want to know why your virtual CmOk() function isn't being called in
   your OWL program, your question is probably more appropriate in the
   Windows programming newsgroup.  If you can write a small stand-alone
   program which exhibits the same undesired compiler error or behavior
   as your OWL program, by all means post here in comp.lang.c++ since C++
   programmers using other systems could be of help.

2. Be descriptive in the subject line.  "C++ problem" leaves a lot to the
   imagination.  "Problem new'ing a multi-dimensional array" is good.
   Refrain from exclamation points, cries for HELPPP, and the once funny
   "SEX SEX SEX."  If you think the problem is specific to your compiler,
   you might want to mention the compiler/version in the subject line.

3. Post code that is complete and compilable.  It's extremely difficult
   to debug or reconstruct a program from a human language description.
   By "complete code" I mean that any types and functions used are
   declared, headers are #include'd, etc.  Please strip the code down to
   the bare essentials.  We don't need a program that does something
   useful at run-time, or even links.  We just need to be able to
   reproduce the undesired compiler error (possibly on a different
   compiler).  By "compilable code" I mean that it doesn't contain a
   bunch of uncommented ellipses or line numbers at the beginning of each
   line:

	14:	#include <iostream.h>
	15:	class Foo { ... };  // this is annoying

   Try to organize the code into one linear program instead of making us cut
   out and create header files.  Be very careful if you are typing the code
   into your article -- it's often difficult to tell whether something is a
   typo or the real cause of the problem.  Try using your editor's
   cut&paste or "insert file" feature instead.

4. Mention what compiler, compiler version, and system you're using.  I
   know, I just said that system-specific questions should go to a
   system-specific newsgroup, but compiler information is often very
   useful in diagnosing the problem: ("yeah, I remember Acme 1.2 having
   lots of problems in this area").  It also warns other users of that
   compiler about possible bugs.

5. Show us the exact compiler and linker options and libraries you used
   when building your program.

6. List the exact error message and where the error was given.  "Virtual
   functions don't work" doesn't tell us whether its a compile-, link-, or
   run-time problem.  If the problem is at run-time, give a good
   description of the behavior and any relevant information about your
   system setup.

7. Include a working e-mail address in your signature.  If the address in
   given your article's "From:" line is not correct, please notify your
   system administrator.  Until it is fixed, add a "Reply-To:" line to
   your headers that uses your correct e-mail address.

8. Please read the rest of this FAQ -- chances are your problem, or a
   closely related problem, is discussed here.  Thank you and I hope these
   suggestions help you find a solution to your problem.

==============================================================================
SECTION 3: Environmental/managerial issues
==============================================================================

Q3: What is OOP?  What is C++?

OO programming techniques are the best way we know of to develop large, complex
software applications and systems.

C++ is an OO programming language.  C++ can be used both as an OOPL and simply
"as a better C."  However if you use it "as a better C," don't expect to get
the benefits of object-oriented programming.

OO hype: the software industry is "failing" to meet demands for large, complex
software systems.  But this "failure" is actually due to our SUCCESSES: our
successes have propelled users to ask for more.  Unfortunately we created a
market hunger that the "structured" analysis, design and programming techniques
couldn't satisfy.  This required us to create a better paradigm.

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

Q4: What are some advantages of C++?

GROWTH OF C++: C++ is by far the most popular OOPL.  The number of C++ users is
doubling every 7.5 to 9 months.  Knowing C++ is a good resume-stuffer (but use
it as an OOPL rather than just as a better C).

ENCAPSULATION: Hiding our data structures allows us to change one chunk of a
system without breaking other chunks.  We provide our software chunks (we call
them "classes") with safe interfaces.  Users of a chunk use its interface only.
The relatively volatile "implementation" of this interface is "encapsulated"
("put into a capsule") to prevent users from becoming reliant on its temporary
decisions.  In simple C, this was done by making a module's data "static", thus
preventing another module from accessing our module's bits.

MULTIPLE INSTANCES: The typical C solution to encapsulation (see above) doesn't
support multiple instances of the data (it's hard to make multiple instances of
a module's "static" data).  If we needed multiple instances in C, we used a
"struct" (but this doesn't support "encapsulation").  In C++, we can have both
multiple instances and encapsulation via a "class": the "public" part of a
class contains the class's interface (normally these are a special kind of
function called a "member function"), and the "private" part of a class
contains the class's implementation (typically these are where the bits live).

INLINE FUNCTION CALLS: In straight C, you can achieve "encapsulated structs" by
putting a "void*" in a struct (the access functions use pointer casts).  This
forfeits type safety, and also imposes a function call to access even trivial
fields of the struct (if you allowed direct access to the struct's fields, the
underlying data structure would be difficult to change since too many chunks
would RELY on it being the "old" way).  Function call overhead is small, but
can add up.  C++ classes allow 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: C++ lets you overload the standard operators on a class,
which lets users exploit their intuition (e.g., "myString + yourString" might
do string concatenation, "myDate++" might increment the date, "z1 * z2" might
multiply complex numbers z1 and z2, "a[i]" might access the "i"th element of
the "linked list" called "a", etc.  You can even have "smart pointers" that
could "point" to a disk record or wherever ("x = *p" could "dereference" such a
pointer, which could seek to the location on disk where p "points" and return
its value").  This allows users to program in the language of the problem
domain rather than in the language of the machine.

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 AND DYNAMIC BINDING: 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 (i.e., a InvertableStack is-a Stack that can also invert itself).
Polymorphism and dynamic binding are 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).  E.g., if a Shape is picked by a mouse,
the Shape might get dragged across the screen and placed into a new location.
Polymorphism and dynamic binding allow the code to work correctly even if the
compiler knows only 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!)

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

Q5: Who uses C++?

Lots and lots of companies and government sites.  Lots.

Statistically, 5 people became new C++ programmers while you read the words of
the previous FAQ.

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

Q6: Are there any C++ standardization efforts underway?

Yes; ANSI (American) and ISO (International) groups are working closely with
each other.  The ANSI-C++ committee is called "X3J16".  The ISO C++ standards
group is called "WG21".  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, etc ad nauseum.
About 70 people attend each meeting.  People come from USA, UK, Japan, Germany,
Sweden, Denmark, France, ... (all have "local" committees sending official
representatives and conducting "local" meetings).

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

Q7: Where can I get a copy of the latest ANSI-C++ draft standard?

ANSI standards and/or drafts are NOT available in machine readable form.  There
is NOT an "ftp" site that has a copy.  You can get a paper copy ($65) from:

	X3 Secretariat
	CBEMA
	1250 I Street NW
	Suite 200
	Washington, DC  20005
	202-626-5738

Ask for the latest version of "Working Paper for Draft Proposed American
National Standard for Information Systems -- Programming Language C++."

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

Q8: Is C++ backward compatible with ANSI-C?

Almost.

C++ is as close as possible to compatible with C, but no closer.  In practice,
the major difference is that C++ requires prototypes, and that "f()" declares a
function that takes no parameters (in C, "f()" is the same as "f(...)").  There
are some very subtle differences as well, like sizeof('x') is equal to
sizeof(char) in C++ but is equal to sizeof(int) in C.  Also, C++ puts structure
"tags" in the same namespace as other names, whereas C requires an explicit
"struct" (the "typedef struct Fred Fred" technique still works, but is
redundant in C++).

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

Q9: How long does it take to learn C++?

Companies like Paradigm Shift, Inc. successfully teach standard industry "short
courses", where we compress a university semester course into one 40hr work
week.  However true mastery takes experience; there's no substitute for time.
Hands-on projects are essential, since they allow concepts to "gel."

It takes 6-12 months to become proficient in C++/OOP.  Less if the developers
have easy access to a "local" body of experts, more if there isn't a "good"
general purpose C++ class library available.  To become one of these experts
who can mentor others takes around 3 years.

Some people never make it.  You don't have a chance unless you are teachable
and have personal drive.  As a bare minimum on "teachability," you have to be
able to admit when you've are wrong.  As a bare minimum on "drive," you must
be willing to put in some extra hours (changing the way you think [a paradigm
shift] is a LOT more painful than learning a few new facts).

==============================================================================
SECTION 4: Basics of the paradigm
==============================================================================

Q10: What is a class?

The fundamental building block of OO software.

A class defines a data type, much like a struct would be in C.  In a computer
science sense, a type consists of both a set of states AND a set of operations
which transition between those states.  Thus "int" is a "type" because it has
both a set of states AND it has 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".

Think of "int" as a class that has methods called "operator++", etc.

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

Q11: What is an object?

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" usually means "an instance of a class."  Thus a class defines
the behavior of possibly many objects (instances).

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

Q12: What is a reference?

An alias (an alternate name) for an object.

References are frequently used for pass-by-reference:

	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.  In other
words, "i" IS "x" -- not a pointer to "x", nor a copy of "x", but "x" itself.
Anything you do to "i" gets done to "x", and vise versa.

Underneath it all, references are typically implemented by pointers.  The
effect is as if you used the C style pass-by-pointer, but the "&" is moved from
the caller into the callee, and you eliminate all the "*"s.

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

Q13: What happens if you assign to a reference?

You change the referrent (the object to which the reference refers).

Remember: the reference IS the referrent, so changing the reference changes the
referrent (a reference is an "Lvalue" [something that can appear on the
"L"eft-hand-side of an assignment statement] for the referrent).

This insight can be pushed a bit farther by allowing references to be RETURNED.
This allows function calls on the left hand side of an assignment statement,
which is useful with operator overloading.

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

Q14: How can you reseat a reference to make it refer to a different object?

No way.

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 (it has no
address; taking the address of a reference gives you the address of the
referrent; remember: the reference IS its referrent).

You can't separate the reference from the referent.

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

Q15: When should I use references, and when should I use pointers?

Use references when you can, and pointers when you have to.

References are usually preferred over ptrs whenever you don't need "reseating"
(see previous FAQ).  This usually means that references are most useful in a
class's public interface.  References 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).

NOTE: Old line C programmers sometimes don't like references since they provide
reference semantics that isn't explicit in the caller's code.  After some C++
experience, however, one quickly realizes this is a form of information hiding,
which is an asset rather than a liability.  E.g., programmers should write code
in the language of the problem rather than the language of the machine.

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

Q16: What's the deal with inline functions?

An inline function is a function whose code gets inserted into the caller's
code stream.  Like a macro, inline functions improve performance by avoiding
the overhead of the call itself and (especially!) by the compiler being able to
optimize THROUGH the call ("procedural integration").  Unlike macros, inline
functions avoid infamous macro errors by evaluating all arguments exactly once
(the "call" is semantically like a regular function call, only faster).  Also
unlike macros, argument types are checked, and necessary conversions are
performed correctly (macros are bad for your health; don't use them unless you
absolutely have to).

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) { /*...*/ }

or by including the function definition itself within a class:

	class Fred {
	public:
	  void f(int i, char c) { /*...*/ }
	};

or by defining the member function as "inline" outside the class:

	class Fred {
	public:
	  void f(int i, char c);
	};

	inline void Fred::f(int i, char c) { /*...*/ }

==============================================================================
SECTION 5: Constructors and destructors
==============================================================================

Q17: What's the deal with constructors?

Constructors build objects from dust.

Constructors are like "init functions"; they turn a pile of arbitrary bits into
a living object.  Minimally they initialize internally used fields.  They may
also allocate resources (memory, files, semaphores, sockets, etc).

"ctor" is a typical abbreviation for constructor.

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

Q18: How can I make a constructor call another constructor as a primitive?

No way.

Dragons be here: if you call another constructor, the compiler initializes a
temporary local object; it does NOT initialize "this" object.  You can combine
both constructors by using a default parameter, or you can share their common
code in a private "init()" member function.

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

Q19: What's the deal with destructors?

A destructor gives an object its last rites.

Destructors are used to release any resources allocated by the object.  E.g., a
Lock class might lock a semaphore, and the destructor will release that
semaphore.  The most common example is when the constructor uses "new", and the
destructor uses "delete".

Destructors are a "prepare to die" method.  They are often abbreviated "dtor".

==============================================================================
SECTION 6: Operator overloading
==============================================================================

Q20: What's the deal with operator overloading?

It allows users of your classes to use intuitive syntax.

Operator overloading allows C/C++ operators to have user-defined meanings on
user-defined types (classes).  They're syntactic sugar for function calls:

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

	#if 0
	  Fred add(Fred, Fred);		//without operator overloading
	  Fred mul(Fred, Fred);
	#else
	  Fred operator+(Fred, Fred);	//with operator overloading
	  Fred operator*(Fred, Fred);
	#endif

	Fred f(Fred a, Fred b, Fred c)
	{
	  #if 0
	    return add(add(mul(a,b), mul(b,c)), mul(c,a));  //without...
	  #else
	    return a*b + b*c + c*a;                         //with...
	  #endif
	}

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

Q21: What operators can/cannot be overloaded?

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 Array {
	public:
	  #if 0
	    int& elem(unsigned i) { if (i>99) error(); return data[i]; }
	  #else
	    int& operator[] (unsigned i) { if (i>99) error(); return data[i]; }
	  #endif
	private:
	  int data[100];
	};

	main()
	{
	  Array a;

	  #if 0
	    a.elem(10) = 42;
	    a.elem(12) += a.elem(13);
	  #else
	    a[10] = 42;
	    a[12] += a[13];
	  #endif
	}

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

Q22: Can I create a "**" operator for "to-the-power-of" operations?

Nope.

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're in doubt, consider that "x ** y" is the same as "x * (*y)" (in other
words, the compiler assumes "y" is a pointer).  Besides, operator overloading
is just syntactic sugar for function calls.  Although this particular syntactic
sugar can be very sweet, it doesn't add anything fundamental.  I suggest you
overload "pow(base,exponent)" (a double precision version is in <math.h>).

BTW: operator^ can work, except it has the wrong precedence and associativity.

==============================================================================
SECTION 7: Friends
==============================================================================

Q23: What is a "friend"?

Something to allow your class to grant access to another class or function.

Friends can be either functions or other classes.  A class grants access
privileges to its friends.  Normally a developer has political and technical
control over both the friends and methods of a class (else you need permission
from the owner of the other pieces when you want to update your class).

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

Q24: Do "friends" violate encapsulation?

If they're used properly, they actually ENHANCE encapsulation.

You often need to split a class in half when the two halves will have different
numbers of instances or different lifetimes.  In these cases, the two halves
usually need direct access to each other (the two halves USED to be in the same
class, so you haven't INCREASED the number of methods that have direct access
to a data structure; you've simply MOVED some of those methods).  The safest
way to implement this is to make the two halves friends of each other.

If you use friends like just described, you'll keep private things private.  In
a naive effort to avoid using friendship in situations like the above, many
people actually destroy encapsulation by either using public data (grotesque!),
or by making the data accessible between the halves via public get/set methods.
Having a public get and set method for a private datum is ok only when the
private datum "makes sense" from outside the class (from a user's perspective).
In many cases, these get/set methods are almost as bad as public data: they
hide (only) the NAMES of the private data members, but they don't hide the
existence of the private data members.

Similarly, if you use friend functions as a syntactic variant of a class's
public access functions, they don't violate encapsulation any more than a
member function violates encapsulation.  In other words, a class's friends and
members ARE the encapsulation barrier, as defined by the class itself.

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

Q25: What are some advantages/disadvantages of using friend functions?

They provide a degree of freedom in the interface design options.

Member fns and friend fns are equally privileged (100% vested).  The major
difference is that a friend function is called like "f(x)", while a member is
called like "x.f()".  Thus friend fns allow the class's designer to select
the syntax that is deemed most readable, which lowers maintenance costs.

The major disadvantage of friend functions is that they require an extra line
of code when you want dynamic binding.  To get the effect of a virtual friend,
the friend function should call a hidden (usually "protected:") virtual member
fn; e.g., "void f(Base& b) { b.do_f(); }".  Derived classes override the hidden
virtual member function ("void Derived::do_f()"), NOT the friend function.

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

Q26: What does it mean that "friendship is neither inherited nor transitive"?

The privileges of friendship aren't inherited: derived classes of a friend
aren't necessarily friends (I may declare you as my friend, but that doesn't
mean I necessarily trust your kids).  If class "Base" declares "f()" to be a
friend, "f()" doesn't have any automatic special access rights to the extra
stuff declared in derived class, "Derived."

The privileges of friendship aren't transitive: friends of a friend class
aren't necessarily friends of the original class (a friend of a friend isn't
necessarily a friend).  E.g., if class "Fred" declares class "Wilma" as a
friend, and class "Wilma" declares "f()" as a friend, "f()" doesn't necessarily
have any special access rights to "Fred".

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

Q27: Should my class declare a member function or a friend function?

Use a member when you can, and a friend when you have to.

Sometimes friends are syntactically better (e.g., in class "Fred", friend fns
allow the "Fred" param to be second, while members require it to be first).
Another good use of friend functions are the binary infix arithmetic operators
(e.g., "aComplex + aComplex" probably should be defined as a friend rather than
a member, since you want to allow "aFloat + aComplex" as well; recall 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 member function invocation).

In other cases, choose a member function over a friend function.

==============================================================================
SECTION 8: Input/output via <iostream.h> and <stdio.h>
==============================================================================

Q28: How can I provide printing for a "class Fred"?

Provide a friend operator<<:

	class Fred {
	public:
	  friend ostream& operator<< (ostream& o, const Fred& fred)
	    { return o << fred.i; }
	  //...
	private:
	  int i;    //just for illustration
	};

We use a friend rather than a member since the "Fred" parameter is second
rather than first.  Input is similar, but the signature is:

	istream& operator>> (istream& i, Fred& fred);
	                              // ^^^^^------- not "const Fred& fred"!

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

Q29: Why should I use <iostream.h> instead of the traditional <stdio.h>?

Increase type safety, reduce errors, improve performance, allow extensibility,
and provide subclassability.

Printf is arguably not broken, and scanf is perhaps livable despite being error
prone, however both are limited with respect to what C++ I/O can do.  C++ I/O
(using "<<" and ">>") is, relative to C (using "printf()" and "scanf()"):

 * Type safe -- type of object being I/O'd is known statically by the compiler,
   rather than via dynamically tested via "%" fields.

 * Less error prone -- redundant info increases the chance of errors.  C++ I/O
   has no redundant "%" tokens to get right.

 * Faster -- printf is an "interpreter" of a tiny language whose constructs
   mainly include "%" fields; it uses these fields to select the right
   formatting primitive at run-time.  C++ I/O picks these routines statically
   based on actual types of the args.  This improves performance.

 * Extensible -- the C++ I/O mechanism allows new user-defined types to be
   added without breaking existing code (imagine the chaos if everyone was
   simultaneously adding new incompatible "%" fields to printf and scanf?!).

 * Subclassable -- ostream and istream (the C++ replacements for FILE*) are
   real classes, and hence subclassable.  This means you can have other user
   defined things that look and act like streams, yet that do whatever strange
   and wonderful things you want.  You automatically get to use the zillions of
   lines of I/O code written by users you don't even know, and they don't need
   to know about your "extended stream" class.

--
Marshall Cline
--
Marshall P. Cline, Ph.D. / Paradigm Shift Inc / PO Box 5108 / Potsdam NY 13676
cline@sun.soe.clarkson.edu / 315-353-6100 / FAX: 315-353-6110

From ankh.iia.org!uunet!library.erc.clarkson.edu!sun.soe.clarkson.edu!cline Sun Dec 18 23:53:21 1994
Path: ankh.iia.org!uunet!library.erc.clarkson.edu!sun.soe.clarkson.edu!cline
From: cline@sun.soe.clarkson.edu (Marshall Cline)
Newsgroups: comp.lang.c++
Subject: C++ FAQ: posting #2/4
Followup-To: comp.lang.c++
Date: 14 Nov 1994 00:26:25 GMT
Organization: Paradigm Shift, Inc (training/consulting/OOD/OOP/C++)
Lines: 834
Sender: cline@sun.soe.clarkson.edu
Distribution: world
Expires: +1 month
Message-ID: <3a6arh$gd7@library.erc.clarkson.edu>
Reply-To: cline@parashift.com (Marshall Cline)
NNTP-Posting-Host: sun.soe.clarkson.edu
Summary: Please read this before posting to comp.lang.c++

comp.lang.c++ Frequently Asked Questions list (with answers, fortunately).
Copyright (C) 1991-94 Marshall P. Cline, Ph.D.
Posting 2 of 4.
Posting #1 explains copying permissions, (no)warranty, table-of-contents, etc

==============================================================================
SECTION 9: Freestore management
==============================================================================

Q30: Does "delete p" delete the pointer "p", or the pointed-to-data, "*p"?

The pointed-to-data.

"delete" really means "delete the thing pointed to by."  The same abuse of
English occurs when "free"ing the memory pointed to by a ptr in C ("free(p)"
really means "free_the_stuff_pointed_to_by(p)").

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

Q31: Can I "free()" pointers allocated with "new"?  Can I "delete" pointers
   alloc'd with "malloc()"?

No.

It is perfectly legal, moral, and wholesome to use malloc/free and new/delete
in the same program, but it is illegal, immoral, and despicable to free a
pointer allocated via new, or to delete a pointer allocated via malloc.

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

Q32: Why should I use "new" instead of trustworthy old malloc()?

Constructors/destructors, type safety, overridability.

Constructors/destructors: unlike "malloc(sizeof(Fred))", "new Fred()" calls
Fred's constructor.  Similarly, "delete p" calls "*p"'s destructor.

Type safety: malloc() returns a "void*" which isn't type safe.  "new Fred()"
returns a ptr of the right type (a "Fred*").

Overridability: "new" is an operator that can be overridden by a class, while
"malloc" is not overridable on a per-class basis.

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

Q33: Why doesn't C++ have a "realloc()" along with "new" and "delete"?

To save you from disaster.

When realloc() has to copy the allocation, it uses a BITWISE copy operation,
which will tear most C++ objects to shreds.  C++ objects should be allowed to
copy themselves: they use their own copy constructor or assignment operator.

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

Q34: How do I allocate / unallocate an array of things?

Use new[] and delete[]:

	Fred* p = new Fred[100];
	//...
	delete [] p;

Any time you use the "[...]" in the "new" expression, you *!*MUST*!* use "[]"
in the "delete" statement.  This syntax is necessary because there is no
syntactic difference between a pointer to a thing and a pointer to an array of
things (something we inherited from C).

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

Q35: What if I forget the "[]" when "delete"ing array allocated via "new
   Fred[n]"?

All life comes to a catastrophic end.

It is the programmer's --not the compiler's-- responsibility to get the
connection between new[] and delete[] correct.  If you get it wrong, neither a
compile-time nor a run-time error message will be generated by the compiler.
Heap corruption is a likely result.  Or worse.  Your program will probably die.

==============================================================================
SECTION 10: Debugging and error handling
==============================================================================

Q36: How can I handle a constructor that fails?

Throw an exception.

Constructors don't have a return type, so it's not possible to use error codes.
The best way to signal constructor failure is therefore to throw an exception.

Before C++ had exceptions, we signaled constructor failure by putting the
object into a "half baked" state (e.g., by setting an internal status bit).
There was a query ("inspector") method to check this bit, that allowed clients
to discover whether they had a live object.  Other member functions would also
check this bit, and, if the object wasn't really alive, do a no-op (or perhaps
something more obnoxious such as "abort()").  This was really ugly.

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

Q37: How should I handle resources if my constructors may throw exceptions?

Every data member inside your object should clean up its own mess.

If a constructor throws an exception, the object's destructor is NOT run.  If
your object has already done something that needs to be undone (such as
allocating some memory, opening a file, or locking a semaphore), this "stuff
that needs to be undone" MUST be remembered by a data member inside the object.

For example, rather than allocating memory into a raw "Fred*" data member, put
the allocated memory into a "smart pointer" member object, and the destructor
of this smart pointer will delete the Fred object when the smart pointer dies.

==============================================================================
SECTION 11: Const correctness
==============================================================================

Q38: What is "const correctness"?

A good thing.

Const correctness uses the keyword "const" to ensure const objects don't get
mutated.  E.g., if function "f()" accepts a "String", and "f()" wants to
promise not to change the "String", you:

 * can either pass by value:	void  f(      String  s   )  { /*...*/ }
 * or by constant reference:	void  f(const String& s   )  { /*...*/ }
 * or by constant pointer:	void  f(const String* sptr)  { /*...*/ }
 * but NOT by non-const ref:	void  f(      String& s   )  { /*...*/ }
 * NOR by non-const pointer:	void  f(      String* sptr)  { /*...*/ }

Attempted changes to "s" within a fn that takes a "const String&" are flagged
as compile-time errors; neither run-time space nor speed is degraded.

Declaring the "constness" of a parameter is just another form of type safety.
It is almost as if a constant String, for example, "lost" its various mutative
operations.  If you find type safety helps you get systems correct (it does;
especially in large systems), you'll find const correctness helps also.

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

Q39: Should I try to get things const correct "sooner" or "later"?

At the very, very, VERY beginning.

Back-patching const correctness results in a snowball effect: every "const" you
add "over here" requires four more to be added "over there."

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

Q40: What is a "const member function"?

A member function that inspects (rather than mutates) its object.

	class Fred {
	public:
	  void f() const;
	};      // ^^^^^--- this implies "fred.f()" won't change "fred"

This means that the ABSTRACT (client-visible) state of the object isn't going
to change (as opposed to promising that the "raw bits of the object's struct
aren't going to change).  C++ compilers aren't allowed to take the "bitwise"
interpretation, since a non-const alias could exist which could modify the
state of the object (gluing a "const" ptr to an object doesn't promise the
object won't change; it only promises that the object won't change VIA THAT
POINTER).

"const" member functions are often called "inspectors."  Non-"const" member
functions are often called "mutators."

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

Q41: What do I do if I want to update an "invisible" data member inside a
   "const" member function?

Use "mutable", or use "const_cast".

A small percentage of inspectors need to make innocuous changes to data members
(e.g., a "Set" object might want to cache its last lookup in hopes of improving
the performance of its next lookup).  By saying the changes are "inocuous," I
mean that the changes wouldn't be visible from outside the object's interface
(otherwise the method would be a mutator rather than an inspector).

When this happens, the data member which will be modified should be marked as
"mutable" (put the "mutable" keyword just before the data member's declaration;
i.e., in the same place where you could put "const").  This tells the compiler
that the data member is allowed to change during a const member function.  If
you can't use "mutable", you can cast away the constness of "this" via
"const_cast".  E.g., in "Set::lookup() const", you might say,

	Set* self = const_cast<Set*>(this);

After this line, "self" will have the same bits as "this" (e.g., "self==this"),
but "self" is a "Set*" rather than a "const Set*".  Therefore you can use
"self" to modify the object pointed to by "this".

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

Q42: Does "const_cast" mean lost optimization opportunities?

In theory, yes; in practice, no.

Even if a compiler outlawed "const_cast", the only way to avoid flushing the
register cache across a "const" member function call would be to ensure that
there are no non-const pointers that alias the object.  This can only happen in
rare cases (when the object is constructed in the scope of the const member fn
invocation, and when all the non-const member function invocations between the
object's construction and the const member fn invocation are statically bound,
and when every one of these invocations is also "inline"d, and when the
constructor itself is "inline"d, and when any member fns the constructor calls
are inline).

==============================================================================
SECTION 12: Inheritance
==============================================================================

Q43: Is inheritance important to C++?

Yep.

Inheritance is what separates abstract data type (ADT) programming from OOP.

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

Q44: When would I use inheritance?

As a specification device.

Human beings abstract things on two dimensions: part-of and kind-of.  A Ford
Taurus is-a-kind-of-a Car, and a Ford Taurus has-a Engine, Tires, etc.  The
part-of hierarchy has been a part of software since the ADT style became
relevant; inheritance adds "the other" major dimension of decomposition.

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

Q45: How do you express inheritance in C++?

By the ": public" syntax:

	class Car : public Vehicle {
	        //^^^^^^^^---- ": public" is pronounced "is-a-kind-of-a'
	  //...
	};

We state the above relationship in several ways:
 * Car is "a kind of a" Vehicle
 * Car is "derived from" Vehicle
 * Car is "a specialized" Vehicle
 * Car is the "subclass" of Vehicle
 * Vehicle is the "base class" of Car
 * Vehicle is the "superclass" of Car (this not as common in the C++ community)

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

Q46: Is it ok to convert a pointer from a derived class to its base class?

Yes.

A derived class is a specialized version of the base class ("Derived is a
kind-of Base").  The upward conversion is perfectly safe, and happens all the
time (if I am pointing at a car, I am in fact pointing at a vehicle):

	void f(Vehicle* v);
	void g(Car* c) { f(c); }	//perfectly safe; no cast

Note that the answer to this FAQ assumes we're talking about "public"
inheritance; see below on "private/protected" inheritance for "the other kind".

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

Q47: Derived* --> Base* works ok; why doesn't Derived** --> Base** work?

C++ allows a Derived* to be converted to a Base*, since a Derived object is a
kind of a Base object.  However trying to convert a Derived** to a Base** is
(correctly) flagged as an error (if it was allowed, the Base** could be
dereferenced (yielding a Base*), and the Base* could be made to point to an
object of a DIFFERENT derived class.  This would be an error.

As a corollary, an array of Deriveds is-NOT-a-kind-of array of Bases.  At
Paradigm Shift, Inc. we use the following example in our C++ training sessions:

               "A bag of apples is NOT a bag of fruit".

If a bag of apples COULD be passed as a bag of fruit, someone could put a
banana into the bag of apples!

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

Q48: Does array-of-Derived is-NOT-a-kind-of array-of-Base mean arrays are
   bad?

Yes, "arrays are evil" (jest kidd'n :-).

There's a very subtle problem with using raw built-in arrays.  Consider this:

	void f(Base* arrayOfBase)
	{
	  arrayOfBase[3].memberfn();
	}

	main()
	{
	  Derived arrayOfDerived[10];
	  f(arrayOfDerived);
	}

The compiler thinks this is perfectly type-safe, since it can convert a
Derived* to a Base*.  But in reality it is horrendously evil: since Derived
might be larger than Base, the array index in f() not only isn't type safe, it
may not even be pointing at a real object!  In general it'll be pointing
somewhere into the innards of some poor Derived.

The root problem is that C++ can't distinguish between a ptr-to-a-thing and a
ptr-to-an-array-of-things.  Naturally C++ "inherited" this feature from C.

NOTE: if we had used an array-like CLASS instead of using a raw array (e.g., an
"Array<T>" rather than a "T[]"), this problem would have been properly trapped
as an error at compile time rather than at run-time.

==============================================================================
SUBSECTION 12A: Inheritance -- Virtual functions
==============================================================================

Q49: What is a "virtual member function"?

A virtual function allows derived classes to replace the implementation
provided by the base class.  The compiler ensures the replacement is always
called whenever the object in question is actually of the derived class, even
if the object is accessed by a base pointer rather than a derived pointer.
This allows algorithms in the base class to be replaced in the derived class,
even if users don't know about the derived class.

Note: the derived class can partially replace ("override") the base class
method (the derived class method can invoke the base class version if desired).

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

Q50: How can C++ achieve dynamic binding yet also static typing?

In the following discussion, "ptr" means either a pointer or a reference.

When you have a ptr, there are two types: the (static) type of the ptr, and the
(dynamic) type of the pointed-to object (the object may actually be of a class
that is derived from the class of the ptr).

"Static typing" means that the "legality" of the call is checked based on the
static type of the ptr: if the type of the ptr can handle the member fn,
certainly the pointed-to object can handle it as well.

"Dynamic binding" means that the "code" that is called is based on the dynamic
type of the pointed-to object.  This is called "dynamic binding," since the
actual code being called is determined dynamically (at run time).

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

Q51: Should a derived class replace ("override") a non-virtual fn from a base
   class?

It's legal, but it ain't moral.

Experienced C++ programmers will sometimes redefine a non-virtual fn for
efficiency (the alternate implementation might make better use of the derived
class' resources), or to get around the hiding rule (see below, and ARM
sect.13.1).  However the client-visible effects must be IDENTICAL, since
non-virtual fns are dispatched based on the static type of the ptr/ref rather
than the dynamic type of the pointed-to/referenced object.

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

Q52: What's the meaning of, "Warning: Derived::f(int) hides Base::f(float)"?

It means you're going to die.

Here's the mess you're in: if Derived declares a member function named "f", and
Base declares a member function named "f" with a different signature (e.g.,
different parameter types and/or constness), then the Base "f" is "hidden"
rather than "overloaded" or "overridden" (even if the Base "f" is virtual).

Here's how you get out of the mess: Derived must redefine the Base member
function(s) that are hidden (even if they are non-virtual).  Normally this
re-definition merely calls the appropriate Base member function.  E.g.,

	class Base {
	public:
	  void f(int);
	};

	class Derived : public Base {
	public:
	  void f(double);
	  void f(int i) { Base::f(i); }
	};             // ^^^^^^^^^^--- redefinition merely calls Base::f(int)

==============================================================================
SUBSECTION 12B: Inheritance -- Conformance
==============================================================================

Q53: Should I hide public member fns inherited from my base class?

Never, never, never do this.  Never.  NEVER!

Attempting to hide (eliminate, revoke) inherited public member functions is an
all-too-common design error.  It usually stems from muddy thinking.

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

Q54: Is a "Circle" a kind-of an "Ellipse"?

Not if Ellipse promises to be able to change its size assymetrically.

For example, suppose Ellipse has a "setSize(x,y)" method, and suppose this
method promises "the Ellipse's width() will be x, and its height() will be y".
In this case, Circle can't be a kind-of Ellipse.  Simply put, if Ellipse can do
something Circle can't, then Circle can't be a kind of Ellipse.

This leaves two potential (valid) relationships between Circle and Ellipse:
 * Make Circle and Ellipse completely unrelated classes.
 * Derive Circle and Ellipse from a base class representing "Ellipses that
   can't NECESSARILY perform an unequal-setSize operation."

In the first case, Ellipse could be derived from class "AsymmetricShape" (with
setSize(x,y) being introduced in AsymmetricShape), and Circle could be derived
from "SymmetricShape," which has a setSize(size) member fn.

In the second case, class "Oval" could only have "setSize(size)" which sets
both the "width()" and the "height()" to "size", then derive both Ellipse and
Circle from Oval.  Ellipse --but not Circle-- adds the "setSize(x,y)" operation
(see the "hiding rule" for a caveat if the same method name "setSize()" is used
for both operations).

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

Q55: Are there other options to the "Circle is/isnot kind-of Ellipse"
   dilemma?

If you claim that all Ellipses can be squashed assymetrically, and you claim
that Circle is a kind-of Ellipse, and you claim that Circle can't be squashed
assymetrically, clearly you've got to adjust (revoke, actually) one of your
claims.  Thus you've either got to get rid of "Ellipse::setSize(x,y)", get rid
of the inheritance relationship between Circle and Ellipse, or admit that your
"Circle"s aren't necessarily circular.

Here are the two most common traps new OO/C++ programmers regularly fall into.
They attempt to use coding hacks to cover up a broken design (they redefine
Circle::setSize(x,y) to throw an exception, call "abort()", or choose the
average of the two parameters, or to be a no-op).  Unfortunately all these
hacks will surprise users, since users are expecting "width() == x" and
"height() == y".

The only rational way out of this would be to weaken the promise made by
Ellipse's "setSize(x,y)" (e.g., you'd have to change it to, "This method MIGHT
set width() to x and height() to y, or it might do NOTHING").  Unfortunately
this dilutes the contract into dribble, since the user can't rely on any
meaningful behavior.  The whole hierarchy therefore begins to be worthless
(it's hard to convince someone to use an object if you have to shrug your
shoulders when asked what the object does for them).

==============================================================================
SUBSECTION 12C: Inheritance -- Access rules
==============================================================================

Q56: Why can't my derived class access "private" things from my base class?

To protect you from future changes to the base class.

Derived classes do not get access to private members of a base class.  This
effectively "seals off" the derived class from any changes made to the private
members of the base class.

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

Q57: What's the difference between "public:", "private:", and "protected:"?

"Private:" is discussed in the previous section, and "public:" means "anyone
can access it."  The third option, "protected:", makes a member (either data
member or member fn) accessible to subclasses.

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

Q58: How can I protect subclasses from breaking when I change internal parts?

A class has two distinct interfaces for two distinct sets of clients:
 * its "public:" interface serves unrelated classes.
 * its "protected:" interface serves derived classes.

Unless you expect all your subclasses to be built by your own team, you should
consider making your base class's bits be "private:", and use "protected:"
inline access functions to access these data.  This way the private bits can
change, but the derived class's code won't break unless you change the
protected access functions.

==============================================================================
SUBSECTION 12D: Inheritance -- Constructors and destructors
==============================================================================

Q59: When my base class's constructor calls a virtual function, why doesn't my
   derived class's override of that virtual function get invoked?

During the Base class's constructor, the object isn't yet a Derived, so if
"Base::Base()" calls a virtual function "virt()", the "Base::virt()" will be
invoked, even if "Derived::virt()" exists.

Similarly, during Base's destructor, the object is no longer a Derived, so when
Base::~Base() calls "virt()", "Base::virt()" gets control, NOT the
"Derived::virt()" override.

You'll quickly see the wisdom of this approach when you imagine the disaster if
"Derived::virt()" touched a member object from the Derived class.

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

Q60: Does a derived class destructor need to explicitly call the base
   destructor?

No, never explicitly call a destructor (where "never" means "rarely").

A derived class's destructor (whether or not you explicitly define one)
AUTOMATICALLY invokes the destructors for member objects and base class
subobjects.  Member objects are destroyed in the reverse order they appear
within the class, then base class subobjects are destroyed in the reverse order
that they appear in the class's list of base classes.

You should ONLY explicitly call a destructor in esoteric situations, such as
when destroying an object created by the "placement new operator."

==============================================================================
SUBSECTION 12E: Inheritance -- Private and protected inheritance
==============================================================================

Q61: How do you express "private inheritance"?

When you use ": private" instead of ": public."  E.g.,

	class Foo : private Bar {
	  //...
	};

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

Q62: How are "private inheritance" and "composition" similar?

Private inheritance is a syntactic variant of composition (has-a).

E.g., the "car has-a engine" relationship can be expressed using composition:

	class Engine {
	public:
	  Engine(int numCylinders);
	  void start();			//starts this Engine
	};

	class Car {
	public:
	  Car() : e_(8) { }		//initializes this Car with 8 cylinders
	  void start() { e_.start(); }	//start this Car by starting its engine
	private:
	  Engine e_;
	};

The same "has-a" relationship can also be expressed using private inheritance:

	class Car : private Engine {
	public:
	  Car() : Engine(8) { }		//initializes this Car with 8 cylinders
	  Engine::start;		//start this Car by starting its engine
	};

There are several similarities between these two forms of composition:
 * in both cases there is exactly one Engine member object contained in a Car.
 * in neither case can users (outsiders) convert a Car* to an Engine*.

There are also several distinctions:
 * the second form is needed if you want to contain several Engines per Car.
 * the first form can introduce unnecessary multiple inheritance.
 * the first form allows members of Car to convert a Car* to an Engine*.
 * the first form allows access to the "protected" members of the base class.
 * the first form allows Car to override Engine's virtual functions.

Note that private inheritance is usually used to gain access into the
"protected:" members of the base class, but this is usually a short-term
solution (translation: a band-aid; see below).

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

Q63: Which should I prefer: composition or private inheritance?

Composition.

Normally you don't WANT to have access to the internals of too many other
classes, and private inheritance gives you some of this extra power (and
responsibility).  But private inheritance isn't evil; it's just more expensive
to maintain, since it increases the probability that someone will change
something that will break your code.

A legitimate, long-term use for private inheritance is when you want to build a
class Fred that uses code in a class Wilma, and the code from class Wilma needs
to invoke methods from your new class, Fred.  In this case, Fred calls
non-virtuals in Wilma, and Wilma calls (usually pure) virtuals in itself, which
are overridden by Fred.  This would be much harder to do with composition.

	class Wilma {
	protected:
	  void fredCallsWilma()
	    { cout << "Wilma::fredCallsWilma()\n"; wilmaCallsFred(); }
	  virtual void wilmaCallsFred() = 0;
	};

	class Fred : private Wilma {
	public:
	  void barney()
	    { cout << "Fred::barney()\n"; Wilma::fredCallsWilma(); }
	protected:
	  virtual void wilmaCallsFred()
	    { cout << "Fred::wilmaCallsFred()\n"; }
	};

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

Q64: Should I pointer-cast from a "privately" derived class to its base
   class?

Generally, No.

From a method or friend of a privately derived class, the relationship to the
base class is known, and the upward conversion from PrivatelyDer* to Base* (or
PrivatelyDer& to Base&) is safe; no cast is needed or recommended.

However users of PrivateDer should avoid this unsafe conversion, since it is
based on a "private" decision of PrivateDer, and is subject to change without
notice.

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

Q65: How is protected inheritance related to private inheritance?

Similarities: both allow overriding virtuals in the private/protected base
class, neither claims the derived is a kind-of its base.

Dissimilarities: protected inheritance allows derived classes of derived
classes to know about the inheritance relationship (it exposes your grand kids
to your implementation details).  This has both benefits (it allows subclasses
of the protected derived class to exploit the relationship to the protected
base class) and costs (the protected derived class can't change the
relationship without potentially breaking further derived classes).

Protected inheritance uses the ": protected" syntax:

	class Car : protected Engine {
	  //...
	};

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

Q66: What are the access rules with "private" and "protected" inheritance?

Take these classes as examples:

	class B                    { /*...*/ };
	class D_priv : private   B { /*...*/ };
	class D_prot : protected B { /*...*/ };
	class D_publ : public    B { /*...*/ };
	class UserClass            { B b; /*...*/ };

None of the subclasses can access anything that is private in B.  In D_priv,
the public and protected parts of B are "private".  In D_prot, the public and
protected parts of B are "protected".  In D_publ, the public parts of B are
public and the protected parts of B are protected (D_publ is-a-kind-of-a B).
Class "UserClass" can only access the public parts of B, which "seals off"
UserClass from B.

To make a public member of B so it is public in D_priv or D_prot, state the
name of the member with a "B::" prefix.  E.g., to make member "B::f(int,float)"
public in D_prot, you would say:

	class D_prot : protected B {
	public:
	  B::f;    //note: not  "B::f(int,float)"
	};

==============================================================================
SECTION 13: Abstraction
==============================================================================

Q67: What's the big deal of separating interface from implementation?

Interfaces are a company's most valuable resources.  Designing an interface
takes longer than whipping together a concrete class which fulfills that
interface.  Furthermore interfaces require the time of more expensive people.

Since interfaces are so valuable, they should be protected from being tarnished
by data structures and other implementation artifacts.  Thus you should
separate interface from implementation.

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

Q68: How do I separate interface from implementation in C++ (like Modula-2)?

Use an ABC (see next FAQ).

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

Q69: What is an ABC ("abstract base class")?

At the design level, an ABC corresponds to an abstract concept.  If you asked a
Mechanic if he repaired Vehicles, he'd probably wonder what KIND-OF Vehicle you
had in mind.  Chances are he doesn't repair space shuttles, ocean liners,
bicycles, or nuclear submarines.  The problem is that the term "Vehicle" is an
abstract concept (e.g., you can't build a "vehicle" unless you know what kind
of vehicle to build).  In C++, class Vehicle would be an ABC, with Bicycle,
SpaceShuttle, etc, being subclasses (an OceanLiner is-a-kind-of-a Vehicle).  In
real-world OOP, ABCs show up all over the place.

As programming language level, an ABC is a class that has one or more pure
virtual member functions (see next FAQ).  You cannot make an object (instance)
of an ABC.

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

Q70: What is a "pure virtual" member function?

A member function of an ABC that you can only implement in a derived class.

Some member functions exist in concept, but can't have any actual defn.  E.g.,
suppose I asked you to draw a Shape at location (x,y) that has size 7.  You'd
ask me "what kind of shape should I draw?" (circles, squares, hexagons, etc,
are drawn differently).  In C++, we indicate the existence of the "draw()'
method, but we recognize it can only be defined in subclasses:

	class Shape {
	public:
	  virtual void draw() const = 0;
	  //...                     ^^^--- "= 0" means it is "pure virtual"
	};

This pure virtual function makes "Shape" an ABC.  If you want, you can think of
the "= 0" syntax as if if the code were at the NULL pointer.  Thus "Shape"
promises a service to its users, yet Shape isn't able to provide any code to
fulfill that promise.  This ensures any actual object created from a [concrete]
class derived of Shape *WILL* have the indicated member fn, even though the
base class doesn't have enough information to actually DEFINE it yet.

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

Q71: How can I provide printing for an entire hierarchy of classes?

Provide a friend operator<< that calls a protected virtual function:

	class Base {
	public:
	  friend ostream& operator<< (ostream& o, const Base& b)
	    { b.print(o); return o; }
	  //...
	protected:
	  virtual void print(ostream& o) const;  //or "=0;" if "Base" is an ABC
	};

	class Derived : public Base {
	protected:
	  virtual void print(ostream& o) const;
	};

Now all subclasses of Base merely provide their own "print(ostream&) const"
member function (they all share the common "<<" operator).  This technique
allows friends to ACT as if they supported dynamic binding.

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

Q72: When should my destructor be virtual?

When you may "delete" a derived object via a base pointer.

Virtual fns bind to the code associated with the class of the object, rather
than with the class of the pointer/ref.  When you say "delete basePtr", and the
base class has a virtual destructor, the destructor that gets invoked is the
one associated with the type of the object *basePtr, rather than the one
associated with the type of the pointer.  This is generally A Good Thing.

To make life easy for you, the only time you wouldn't want to make a class's
destructor virtual is if that class has NO virtual fns, since the introduction
of the first virtual fn imposes some space overhead in each object (typically
one machine word).  This is how the compiler implements the magic of dynamic
binding; it usually boils down to an extra ptr per object called the "virtual
table pointer" or "vptr".

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

Q73: What is a "virtual constructor"?

An idiom that allows you to do something that C++ doesn't directly support.

You can get the effect of virtual constructor by a virtual "createCopy()"
member fn (for copy constructing), or a virtual "createSimilar()" member fn
(for the default constructor).

	class Shape {
	public:
	  virtual ~Shape() { }		//see on "virtual destructors" for more
	  virtual void draw() = 0;
	  virtual void move() = 0;
	  //...
	  virtual Shape* createCopy() const = 0;
	  virtual Shape* createSimilar() const = 0;
	};

	class Circle : public Shape {
	public:
	  Circle* createCopy()    const { return new Circle(*this); }
	  Circle* createSimilar() const { return new Circle(); }
	  //...
	};

The invocation of "Circle(*this)" is that of copy construction ("*this" has
type "const Circle&" in these methods).  "createSimilar()" is similar, but it
constructs a "default" Circle.

Users use these as if they were "virtual constructors":

	void userCode(Shape& s)
	{
	  Shape* s2 = s.createCopy();
	  Shape* s3 = s.createSimilar();
	  //...
	  delete s2;	//relies on destructor being virtual!!
	  delete s3;	// ditto
	}

This fn will work correctly regardless of whether the Shape is a Circle,
Square, or some other kind-of Shape that doesn't even exist yet.

--
Marshall Cline
--
Marshall P. Cline, Ph.D. / Paradigm Shift Inc / PO Box 5108 / Potsdam NY 13676
cline@sun.soe.clarkson.edu / 315-353-6100 / FAX: 315-353-6110

From ankh.iia.org!uunet!news.mathworks.com!news.kei.com!ub!library.erc.clarkson.edu!sun.soe.clarkson.edu!cline Sun Dec 18 23:53:22 1994
Path: ankh.iia.org!uunet!news.mathworks.com!news.kei.com!ub!library.erc.clarkson.edu!sun.soe.clarkson.edu!cline
From: cline@sun.soe.clarkson.edu (Marshall Cline)
Newsgroups: comp.lang.c++
Subject: C++ FAQ: posting #2/4
Followup-To: comp.lang.c++
Date: 13 Dec 1994 05:57:42 GMT
Organization: Paradigm Shift, Inc (training/consulting/OOD/OOP/C++)
Lines: 834
Sender: cline@sun.soe.clarkson.edu
Distribution: world
Expires: +1 month
Message-ID: <3cjd4m$gke@library.erc.clarkson.edu>
Reply-To: cline@parashift.com (Marshall Cline)
NNTP-Posting-Host: sun.soe.clarkson.edu
Summary: Please read this before posting to comp.lang.c++

comp.lang.c++ Frequently Asked Questions list (with answers, fortunately).
Copyright (C) 1991-94 Marshall P. Cline, Ph.D.
Posting 2 of 4.
Posting #1 explains copying permissions, (no)warranty, table-of-contents, etc

==============================================================================
SECTION 9: Freestore management
==============================================================================

Q30: Does "delete p" delete the pointer "p", or the pointed-to-data, "*p"?

The pointed-to-data.

"delete" really means "delete the thing pointed to by."  The same abuse of
English occurs when "free"ing the memory pointed to by a ptr in C ("free(p)"
really means "free_the_stuff_pointed_to_by(p)").

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

Q31: Can I "free()" pointers allocated with "new"?  Can I "delete" pointers
   alloc'd with "malloc()"?

No.

It is perfectly legal, moral, and wholesome to use malloc/free and new/delete
in the same program, but it is illegal, immoral, and despicable to free a
pointer allocated via new, or to delete a pointer allocated via malloc.

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

Q32: Why should I use "new" instead of trustworthy old malloc()?

Constructors/destructors, type safety, overridability.

Constructors/destructors: unlike "malloc(sizeof(Fred))", "new Fred()" calls
Fred's constructor.  Similarly, "delete p" calls "*p"'s destructor.

Type safety: malloc() returns a "void*" which isn't type safe.  "new Fred()"
returns a ptr of the right type (a "Fred*").

Overridability: "new" is an operator that can be overridden by a class, while
"malloc" is not overridable on a per-class basis.

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

Q33: Why doesn't C++ have a "realloc()" along with "new" and "delete"?

To save you from disaster.

When realloc() has to copy the allocation, it uses a BITWISE copy operation,
which will tear most C++ objects to shreds.  C++ objects should be allowed to
copy themselves: they use their own copy constructor or assignment operator.

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

Q34: How do I allocate / unallocate an array of things?

Use new[] and delete[]:

	Fred* p = new Fred[100];
	//...
	delete [] p;

Any time you use the "[...]" in the "new" expression, you *!*MUST*!* use "[]"
in the "delete" statement.  This syntax is necessary because there is no
syntactic difference between a pointer to a thing and a pointer to an array of
things (something we inherited from C).

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

Q35: What if I forget the "[]" when "delete"ing array allocated via "new
   Fred[n]"?

All life comes to a catastrophic end.

It is the programmer's --not the compiler's-- responsibility to get the
connection between new[] and delete[] correct.  If you get it wrong, neither a
compile-time nor a run-time error message will be generated by the compiler.
Heap corruption is a likely result.  Or worse.  Your program will probably die.

==============================================================================
SECTION 10: Debugging and error handling
==============================================================================

Q36: How can I handle a constructor that fails?

Throw an exception.

Constructors don't have a return type, so it's not possible to use error codes.
The best way to signal constructor failure is therefore to throw an exception.

Before C++ had exceptions, we signaled constructor failure by putting the
object into a "half baked" state (e.g., by setting an internal status bit).
There was a query ("inspector") method to check this bit, that allowed clients
to discover whether they had a live object.  Other member functions would also
check this bit, and, if the object wasn't really alive, do a no-op (or perhaps
something more obnoxious such as "abort()").  This was really ugly.

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

Q37: How should I handle resources if my constructors may throw exceptions?

Every data member inside your object should clean up its own mess.

If a constructor throws an exception, the object's destructor is NOT run.  If
your object has already done something that needs to be undone (such as
allocating some memory, opening a file, or locking a semaphore), this "stuff
that needs to be undone" MUST be remembered by a data member inside the object.

For example, rather than allocating memory into a raw "Fred*" data member, put
the allocated memory into a "smart pointer" member object, and the destructor
of this smart pointer will delete the Fred object when the smart pointer dies.

==============================================================================
SECTION 11: Const correctness
==============================================================================

Q38: What is "const correctness"?

A good thing.

Const correctness uses the keyword "const" to ensure const objects don't get
mutated.  E.g., if function "f()" accepts a "String", and "f()" wants to
promise not to change the "String", you:

 * can either pass by value:	void  f(      String  s   )  { /*...*/ }
 * or by constant reference:	void  f(const String& s   )  { /*...*/ }
 * or by constant pointer:	void  f(const String* sptr)  { /*...*/ }
 * but NOT by non-const ref:	void  f(      String& s   )  { /*...*/ }
 * NOR by non-const pointer:	void  f(      String* sptr)  { /*...*/ }

Attempted changes to "s" within a fn that takes a "const String&" are flagged
as compile-time errors; neither run-time space nor speed is degraded.

Declaring the "constness" of a parameter is just another form of type safety.
It is almost as if a constant String, for example, "lost" its various mutative
operations.  If you find type safety helps you get systems correct (it does;
especially in large systems), you'll find const correctness helps also.

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

Q39: Should I try to get things const correct "sooner" or "later"?

At the very, very, VERY beginning.

Back-patching const correctness results in a snowball effect: every "const" you
add "over here" requires four more to be added "over there."

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

Q40: What is a "const member function"?

A member function that inspects (rather than mutates) its object.

	class Fred {
	public:
	  void f() const;
	};      // ^^^^^--- this implies "fred.f()" won't change "fred"

This means that the ABSTRACT (client-visible) state of the object isn't going
to change (as opposed to promising that the "raw bits of the object's struct
aren't going to change).  C++ compilers aren't allowed to take the "bitwise"
interpretation, since a non-const alias could exist which could modify the
state of the object (gluing a "const" ptr to an object doesn't promise the
object won't change; it promises only that the object won't change VIA THAT
POINTER).

"const" member functions are often called "inspectors."  Non-"const" member
functions are often called "mutators."

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

Q41: What do I do if I want to update an "invisible" data member inside a
   "const" member function?

Use "mutable", or use "const_cast".

A small percentage of inspectors need to make innocuous changes to data members
(e.g., a "Set" object might want to cache its last lookup in hopes of improving
the performance of its next lookup).  By saying the changes are "inocuous," I
mean that the changes wouldn't be visible from outside the object's interface
(otherwise the method would be a mutator rather than an inspector).

When this happens, the data member which will be modified should be marked as
"mutable" (put the "mutable" keyword just before the data member's declaration;
i.e., in the same place where you could put "const").  This tells the compiler
that the data member is allowed to change during a const member function.  If
you can't use "mutable", you can cast away the constness of "this" via
"const_cast".  E.g., in "Set::lookup() const", you might say,

	Set* self = const_cast<Set*>(this);

After this line, "self" will have the same bits as "this" (e.g., "self==this"),
but "self" is a "Set*" rather than a "const Set*".  Therefore you can use
"self" to modify the object pointed to by "this".

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

Q42: Does "const_cast" mean lost optimization opportunities?

In theory, yes; in practice, no.

Even if a compiler outlawed "const_cast", the only way to avoid flushing the
register cache across a "const" member function call would be to ensure that
there are no non-const pointers that alias the object.  This can happen only in
rare cases (when the object is constructed in the scope of the const member fn
invocation, and when all the non-const member function invocations between the
object's construction and the const member fn invocation are statically bound,
and when every one of these invocations is also "inline"d, and when the
constructor itself is "inline"d, and when any member fns the constructor calls
are inline).

==============================================================================
SECTION 12: Inheritance
==============================================================================

Q43: Is inheritance important to C++?

Yep.

Inheritance is what separates abstract data type (ADT) programming from OOP.

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

Q44: When would I use inheritance?

As a specification device.

Human beings abstract things on two dimensions: part-of and kind-of.  A Ford
Taurus is-a-kind-of-a Car, and a Ford Taurus has-a Engine, Tires, etc.  The
part-of hierarchy has been a part of software since the ADT style became
relevant; inheritance adds "the other" major dimension of decomposition.

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

Q45: How do you express inheritance in C++?

By the ": public" syntax:

	class Car : public Vehicle {
	        //^^^^^^^^---- ": public" is pronounced "is-a-kind-of-a'
	  //...
	};

We state the above relationship in several ways:
 * Car is "a kind of a" Vehicle
 * Car is "derived from" Vehicle
 * Car is "a specialized" Vehicle
 * Car is the "subclass" of Vehicle
 * Vehicle is the "base class" of Car
 * Vehicle is the "superclass" of Car (this not as common in the C++ community)

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

Q46: Is it ok to convert a pointer from a derived class to its base class?

Yes.

A derived class is a specialized version of the base class ("Derived is a
kind-of Base").  The upward conversion is perfectly safe, and happens all the
time (if I am pointing at a car, I am in fact pointing at a vehicle):

	void f(Vehicle* v);
	void g(Car* c) { f(c); }	//perfectly safe; no cast

Note that the answer to this FAQ assumes we're talking about "public"
inheritance; see below on "private/protected" inheritance for "the other kind".

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

Q47: Derived* --> Base* works ok; why doesn't Derived** --> Base** work?

C++ allows a Derived* to be converted to a Base*, since a Derived object is a
kind of a Base object.  However trying to convert a Derived** to a Base** is
(correctly) flagged as an error (if it was allowed, the Base** could be
dereferenced (yielding a Base*), and the Base* could be made to point to an
object of a DIFFERENT derived class.  This would be an error.

As a corollary, an array of Deriveds is-NOT-a-kind-of array of Bases.  At
Paradigm Shift, Inc. we use the following example in our C++ training sessions:

               "A bag of apples is NOT a bag of fruit".

If a bag of apples COULD be passed as a bag of fruit, someone could put a
banana into the bag of apples!

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

Q48: Does array-of-Derived is-NOT-a-kind-of array-of-Base mean arrays are
   bad?

Yes, "arrays are evil" (jest kidd'n :-).

There's a very subtle problem with using raw built-in arrays.  Consider this:

	void f(Base* arrayOfBase)
	{
	  arrayOfBase[3].memberfn();
	}

	main()
	{
	  Derived arrayOfDerived[10];
	  f(arrayOfDerived);
	}

The compiler thinks this is perfectly type-safe, since it can convert a
Derived* to a Base*.  But in reality it is horrendously evil: since Derived
might be larger than Base, the array index in f() not only isn't type safe, it
may not even be pointing at a real object!  In general it'll be pointing
somewhere into the innards of some poor Derived.

The root problem is that C++ can't distinguish between a ptr-to-a-thing and a
ptr-to-an-array-of-things.  Naturally C++ "inherited" this feature from C.

NOTE: if we had used an array-like CLASS instead of using a raw array (e.g., an
"Array<T>" rather than a "T[]"), this problem would have been properly trapped
as an error at compile time rather than at run-time.

==============================================================================
SUBSECTION 12A: Inheritance -- Virtual functions
==============================================================================

Q49: What is a "virtual member function"?

A virtual function allows derived classes to replace the implementation
provided by the base class.  The compiler ensures the replacement is always
called whenever the object in question is actually of the derived class, even
if the object is accessed by a base pointer rather than a derived pointer.
This allows algorithms in the base class to be replaced in the derived class,
even if users don't know about the derived class.

Note: the derived class can partially replace ("override") the base class
method (the derived class method can invoke the base class version if desired).

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

Q50: How can C++ achieve dynamic binding yet also static typing?

In the following discussion, "ptr" means either a pointer or a reference.

When you have a ptr, there are two types: the (static) type of the ptr, and the
(dynamic) type of the pointed-to object (the object may actually be of a class
that is derived from the class of the ptr).

"Static typing" means that the "legality" of the call is checked based on the
static type of the ptr: if the type of the ptr can handle the member fn,
certainly the pointed-to object can handle it as well.

"Dynamic binding" means that the "code" that is called is based on the dynamic
type of the pointed-to object.  This is called "dynamic binding," since the
actual code being called is determined dynamically (at run time).

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

Q51: Should a derived class replace ("override") a non-virtual fn from a base
   class?

It's legal, but it ain't moral.

Experienced C++ programmers will sometimes redefine a non-virtual fn for
efficiency (the alternate implementation might make better use of the derived
class' resources), or to get around the hiding rule (see below, and ARM
sect.13.1).  However the client-visible effects must be IDENTICAL, since
non-virtual fns are dispatched based on the static type of the ptr/ref rather
than the dynamic type of the pointed-to/referenced object.

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

Q52: What's the meaning of, "Warning: Derived::f(int) hides Base::f(float)"?

It means you're going to die.

Here's the mess you're in: if Derived declares a member function named "f", and
Base declares a member function named "f" with a different signature (e.g.,
different parameter types and/or constness), then the Base "f" is "hidden"
rather than "overloaded" or "overridden" (even if the Base "f" is virtual).

Here's how you get out of the mess: Derived must redefine the Base member
function(s) that are hidden (even if they are non-virtual).  Normally this
re-definition merely calls the appropriate Base member function.  E.g.,

	class Base {
	public:
	  void f(int);
	};

	class Derived : public Base {
	public:
	  void f(double);
	  void f(int i) { Base::f(i); }
	};             // ^^^^^^^^^^--- redefinition merely calls Base::f(int)

==============================================================================
SUBSECTION 12B: Inheritance -- Conformance
==============================================================================

Q53: Should I hide public member fns inherited from my base class?

Never, never, never do this.  Never.  NEVER!

Attempting to hide (eliminate, revoke) inherited public member functions is an
all-too-common design error.  It usually stems from muddy thinking.

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

Q54: Is a "Circle" a kind-of an "Ellipse"?

Not if Ellipse promises to be able to change its size asymmetrically.

For example, suppose Ellipse has a "setSize(x,y)" method, and suppose this
method promises "the Ellipse's width() will be x, and its height() will be y".
In this case, Circle can't be a kind-of Ellipse.  Simply put, if Ellipse can do
something Circle can't, then Circle can't be a kind of Ellipse.

This leaves two potential (valid) relationships between Circle and Ellipse:
 * Make Circle and Ellipse completely unrelated classes.
 * Derive Circle and Ellipse from a base class representing "Ellipses that
   can't NECESSARILY perform an unequal-setSize operation."

In the first case, Ellipse could be derived from class "AsymmetricShape" (with
setSize(x,y) being introduced in AsymmetricShape), and Circle could be derived
from "SymmetricShape," which has a setSize(size) member fn.

In the second case, class "Oval" could only have "setSize(size)" which sets
both the "width()" and the "height()" to "size", then derive both Ellipse and
Circle from Oval.  Ellipse --but not Circle-- adds the "setSize(x,y)" operation
(see the "hiding rule" for a caveat if the same method name "setSize()" is used
for both operations).

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

Q55: Are there other options to the "Circle is/isnot kind-of Ellipse"
   dilemma?

If you claim that all Ellipses can be squashed asymmetrically, and you claim
that Circle is a kind-of Ellipse, and you claim that Circle can't be squashed
asymmetrically, clearly you've got to adjust (revoke, actually) one of your
claims.  Thus you've either got to get rid of "Ellipse::setSize(x,y)", get rid
of the inheritance relationship between Circle and Ellipse, or admit that your
"Circle"s aren't necessarily circular.

Here are the two most common traps new OO/C++ programmers regularly fall into.
They attempt to use coding hacks to cover up a broken design (they redefine
Circle::setSize(x,y) to throw an exception, call "abort()", or choose the
average of the two parameters, or to be a no-op).  Unfortunately all these
hacks will surprise users, since users are expecting "width() == x" and
"height() == y".

The only rational way out of this would be to weaken the promise made by
Ellipse's "setSize(x,y)" (e.g., you'd have to change it to, "This method MIGHT
set width() to x and height() to y, or it might do NOTHING").  Unfortunately
this dilutes the contract into dribble, since the user can't rely on any
meaningful behavior.  The whole hierarchy therefore begins to be worthless
(it's hard to convince someone to use an object if you have to shrug your
shoulders when asked what the object does for them).

==============================================================================
SUBSECTION 12C: Inheritance -- Access rules
==============================================================================

Q56: Why can't my derived class access "private" things from my base class?

To protect you from future changes to the base class.

Derived classes do not get access to private members of a base class.  This
effectively "seals off" the derived class from any changes made to the private
members of the base class.

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

Q57: What's the difference between "public:", "private:", and "protected:"?

"Private:" is discussed in the previous section, and "public:" means "anyone
can access it."  The third option, "protected:", makes a member (either data
member or member fn) accessible to subclasses.

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

Q58: How can I protect subclasses from breaking when I change internal parts?

A class has two distinct interfaces for two distinct sets of clients:
 * its "public:" interface serves unrelated classes.
 * its "protected:" interface serves derived classes.

Unless you expect all your subclasses to be built by your own team, you should
consider making your base class's bits be "private:", and use "protected:"
inline access functions to access these data.  This way the private bits can
change, but the derived class's code won't break unless you change the
protected access functions.

==============================================================================
SUBSECTION 12D: Inheritance -- Constructors and destructors
==============================================================================

Q59: When my base class's constructor calls a virtual function, why doesn't my
   derived class's override of that virtual function get invoked?

During the Base class's constructor, the object isn't yet a Derived, so if
"Base::Base()" calls a virtual function "virt()", the "Base::virt()" will be
invoked, even if "Derived::virt()" exists.

Similarly, during Base's destructor, the object is no longer a Derived, so when
Base::~Base() calls "virt()", "Base::virt()" gets control, NOT the
"Derived::virt()" override.

You'll quickly see the wisdom of this approach when you imagine the disaster if
"Derived::virt()" touched a member object from the Derived class.

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

Q60: Does a derived class destructor need to explicitly call the base
   destructor?

No, never explicitly call a destructor (where "never" means "rarely").

A derived class's destructor (whether or not you explicitly define one)
AUTOMATICALLY invokes the destructors for member objects and base class
subobjects.  Member objects are destroyed in the reverse order they appear
within the class, then base class subobjects are destroyed in the reverse order
that they appear in the class's list of base classes.

You should explicitly call a destructor ONLY in esoteric situations, such as
when destroying an object created by the "placement new operator."

==============================================================================
SUBSECTION 12E: Inheritance -- Private and protected inheritance
==============================================================================

Q61: How do you express "private inheritance"?

When you use ": private" instead of ": public."  E.g.,

	class Foo : private Bar {
	  //...
	};

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

Q62: How are "private inheritance" and "composition" similar?

Private inheritance is a syntactic variant of composition (has-a).

E.g., the "car has-a engine" relationship can be expressed using composition:

	class Engine {
	public:
	  Engine(int numCylinders);
	  void start();			//starts this Engine
	};

	class Car {
	public:
	  Car() : e_(8) { }		//initializes this Car with 8 cylinders
	  void start() { e_.start(); }	//start this Car by starting its engine
	private:
	  Engine e_;
	};

The same "has-a" relationship can also be expressed using private inheritance:

	class Car : private Engine {
	public:
	  Car() : Engine(8) { }		//initializes this Car with 8 cylinders
	  Engine::start;		//start this Car by starting its engine
	};

There are several similarities between these two forms of composition:
 * in both cases there is exactly one Engine member object contained in a Car.
 * in neither case can users (outsiders) convert a Car* to an Engine*.

There are also several distinctions:
 * the first form is needed if you want to contain several Engines per Car.
 * the second form can introduce unnecessary multiple inheritance.
 * the second form allows members of Car to convert a Car* to an Engine*.
 * the second form allows access to the "protected" members of the base class.
 * the second form allows Car to override Engine's virtual functions.

Note that private inheritance is usually used to gain access into the
"protected:" members of the base class, but this is usually a short-term
solution (translation: a band-aid; see below).

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

Q63: Which should I prefer: composition or private inheritance?

Composition.

Normally you don't WANT to have access to the internals of too many other
classes, and private inheritance gives you some of this extra power (and
responsibility).  But private inheritance isn't evil; it's just more expensive
to maintain, since it increases the probability that someone will change
something that will break your code.

A legitimate, long-term use for private inheritance is when you want to build a
class Fred that uses code in a class Wilma, and the code from class Wilma needs
to invoke methods from your new class, Fred.  In this case, Fred calls
non-virtuals in Wilma, and Wilma calls (usually pure) virtuals in itself, which
are overridden by Fred.  This would be much harder to do with composition.

	class Wilma {
	protected:
	  void fredCallsWilma()
	    { cout << "Wilma::fredCallsWilma()\n"; wilmaCallsFred(); }
	  virtual void wilmaCallsFred() = 0;
	};

	class Fred : private Wilma {
	public:
	  void barney()
	    { cout << "Fred::barney()\n"; Wilma::fredCallsWilma(); }
	protected:
	  virtual void wilmaCallsFred()
	    { cout << "Fred::wilmaCallsFred()\n"; }
	};

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

Q64: Should I pointer-cast from a "privately" derived class to its base
   class?

Generally, No.

From a method or friend of a privately derived class, the relationship to the
base class is known, and the upward conversion from PrivatelyDer* to Base* (or
PrivatelyDer& to Base&) is safe; no cast is needed or recommended.

However users of PrivateDer should avoid this unsafe conversion, since it is
based on a "private" decision of PrivateDer, and is subject to change without
notice.

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

Q65: How is protected inheritance related to private inheritance?

Similarities: both allow overriding virtuals in the private/protected base
class, neither claims the derived is a kind-of its base.

Dissimilarities: protected inheritance allows derived classes of derived
classes to know about the inheritance relationship (it exposes your grand kids
to your implementation details).  This has both benefits (it allows subclasses
of the protected derived class to exploit the relationship to the protected
base class) and costs (the protected derived class can't change the
relationship without potentially breaking further derived classes).

Protected inheritance uses the ": protected" syntax:

	class Car : protected Engine {
	  //...
	};

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

Q66: What are the access rules with "private" and "protected" inheritance?

Take these classes as examples:

	class B                    { /*...*/ };
	class D_priv : private   B { /*...*/ };
	class D_prot : protected B { /*...*/ };
	class D_publ : public    B { /*...*/ };
	class UserClass            { B b; /*...*/ };

None of the subclasses can access anything that is private in B.  In D_priv,
the public and protected parts of B are "private".  In D_prot, the public and
protected parts of B are "protected".  In D_publ, the public parts of B are
public and the protected parts of B are protected (D_publ is-a-kind-of-a B).
Class "UserClass" can access only the public parts of B, which "seals off"
UserClass from B.

To make a public member of B so it is public in D_priv or D_prot, state the
name of the member with a "B::" prefix.  E.g., to make member "B::f(int,float)"
public in D_prot, you would say:

	class D_prot : protected B {
	public:
	  B::f;    //note: not  "B::f(int,float)"
	};

==============================================================================
SECTION 13: Abstraction
==============================================================================

Q67: What's the big deal of separating interface from implementation?

Interfaces are a company's most valuable resources.  Designing an interface
takes longer than whipping together a concrete class which fulfills that
interface.  Furthermore interfaces require the time of more expensive people.

Since interfaces are so valuable, they should be protected from being tarnished
by data structures and other implementation artifacts.  Thus you should
separate interface from implementation.

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

Q68: How do I separate interface from implementation in C++ (like Modula-2)?

Use an ABC (see next FAQ).

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

Q69: What is an ABC ("abstract base class")?

At the design level, an ABC corresponds to an abstract concept.  If you asked a
Mechanic if he repaired Vehicles, he'd probably wonder what KIND-OF Vehicle you
had in mind.  Chances are he doesn't repair space shuttles, ocean liners,
bicycles, or nuclear submarines.  The problem is that the term "Vehicle" is an
abstract concept (e.g., you can't build a "vehicle" unless you know what kind
of vehicle to build).  In C++, class Vehicle would be an ABC, with Bicycle,
SpaceShuttle, etc, being subclasses (an OceanLiner is-a-kind-of-a Vehicle).  In
real-world OOP, ABCs show up all over the place.

As programming language level, an ABC is a class that has one or more pure
virtual member functions (see next FAQ).  You cannot make an object (instance)
of an ABC.

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

Q70: What is a "pure virtual" member function?

A member function of an ABC that you can implement only in a derived class.

Some member functions exist in concept, but can't have any actual defn.  E.g.,
suppose I asked you to draw a Shape at location (x,y) that has size 7.  You'd
ask me "what kind of shape should I draw?" (circles, squares, hexagons, etc,
are drawn differently).  In C++, we indicate the existence of the "draw()"
method, but we recognize it can (logically) be defined only in subclasses:

	class Shape {
	public:
	  virtual void draw() const = 0;
	  //...                     ^^^--- "= 0" means it is "pure virtual"
	};

This pure virtual function makes "Shape" an ABC.  If you want, you can think of
the "= 0" syntax as if the code were at the NULL pointer.  Thus "Shape"
promises a service to its users, yet Shape isn't able to provide any code to
fulfill that promise.  This ensures any actual object created from a [concrete]
class derived of Shape *WILL* have the indicated member fn, even though the
base class doesn't have enough information to actually DEFINE it yet.

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

Q71: How can I provide printing for an entire hierarchy of classes?

Provide a friend operator<< that calls a protected virtual function:

	class Base {
	public:
	  friend ostream& operator<< (ostream& o, const Base& b)
	    { b.print(o); return o; }
	  //...
	protected:
	  virtual void print(ostream& o) const;  //or "=0;" if "Base" is an ABC
	};

	class Derived : public Base {
	protected:
	  virtual void print(ostream& o) const;
	};

Now all subclasses of Base merely provide their own "print(ostream&) const"
member function (they all share the common "<<" operator).  This technique
allows friends to ACT as if they supported dynamic binding.

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

Q72: When should my destructor be virtual?

When you may "delete" a derived object via a base pointer.

Virtual fns bind to the code associated with the class of the object, rather
than with the class of the pointer/ref.  When you say "delete basePtr", and the
base class has a virtual destructor, the destructor that gets invoked is the
one associated with the type of the object *basePtr, rather than the one
associated with the type of the pointer.  This is generally A Good Thing.

To make life easy for you, the only time you wouldn't want to make a class's
destructor virtual is if that class has NO virtual fns, since the introduction
of the first virtual fn imposes some space overhead in each object (typically
one machine word).  This is how the compiler implements the magic of dynamic
binding; it usually boils down to an extra ptr per object called the "virtual
table pointer" or "vptr".

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

Q73: What is a "virtual constructor"?

An idiom that allows you to do something that C++ doesn't directly support.

You can get the effect of virtual constructor by a virtual "createCopy()"
member fn (for copy constructing), or a virtual "createSimilar()" member fn
(for the default constructor).

	class Shape {
	public:
	  virtual ~Shape() { }		//see on "virtual destructors" for more
	  virtual void draw() = 0;
	  virtual void move() = 0;
	  //...
	  virtual Shape* createCopy() const = 0;
	  virtual Shape* createSimilar() const = 0;
	};

	class Circle : public Shape {
	public:
	  Circle* createCopy()    const { return new Circle(*this); }
	  Circle* createSimilar() const { return new Circle(); }
	  //...
	};

The invocation of "Circle(*this)" is that of copy construction ("*this" has
type "const Circle&" in these methods).  "createSimilar()" is similar, but it
constructs a "default" Circle.

Users use these as if they were "virtual constructors":

	void userCode(Shape& s)
	{
	  Shape* s2 = s.createCopy();
	  Shape* s3 = s.createSimilar();
	  //...
	  delete s2;	//relies on destructor being virtual!!
	  delete s3;	// ditto
	}

This fn will work correctly regardless of whether the Shape is a Circle,
Square, or some other kind-of Shape that doesn't even exist yet.

--
Marshall Cline
--
Marshall P. Cline, Ph.D. / Paradigm Shift Inc / PO Box 5108 / Potsdam NY 13676
cline@sun.soe.clarkson.edu / 315-353-6100 / FAX: 315-353-6110

From ankh.iia.org!uunet!library.erc.clarkson.edu!sun.soe.clarkson.edu!cline Sun Dec 18 23:53:22 1994
Path: ankh.iia.org!uunet!library.erc.clarkson.edu!sun.soe.clarkson.edu!cline
From: cline@sun.soe.clarkson.edu (Marshall Cline)
Newsgroups: comp.lang.c++
Subject: C++ FAQ: posting #3/4
Followup-To: comp.lang.c++
Date: 14 Nov 1994 00:26:37 GMT
Organization: Paradigm Shift, Inc (training/consulting/OOD/OOP/C++)
Lines: 639
Sender: cline@sun.soe.clarkson.edu
Distribution: world
Expires: +1 month
Message-ID: <3a6art$gd8@library.erc.clarkson.edu>
Reply-To: cline@parashift.com (Marshall Cline)
NNTP-Posting-Host: sun.soe.clarkson.edu
Summary: Please read this before posting to comp.lang.c++

comp.lang.c++ Frequently Asked Questions list (with answers, fortunately).
Copyright (C) 1991-94 Marshall P. Cline, Ph.D.
Posting 3 of 4.
Posting #1 explains copying permissions, (no)warranty, table-of-contents, etc

==============================================================================
SECTION 14: Style guidelines
==============================================================================

Q74: What are some good C++ coding standards?

Thank you for reading this answer rather than just trying to set your own
coding standards.

But please don't ask this question on comp.lang.c++.  Nearly every software
engineer has, at some point, felt that coding standards are or can be used as a
"power play."  Furthermore some attempts to set C++ coding standards have been
made by those unfamiliar with the language and/or paradigm, so the standards
end up being based on what WAS the state-of-the-art when the standards setters
where writing code.  Such impositions generate an attitude of mistrust for
coding standards.

Obviously anyone who asks this question on comp.lang.c++ wants to be trained so
they DON'T run off on their own ignorance, but nonetheless the answers tend to
generate more heat than light.

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

Q75: Are coding standards necessary?  Are they sufficient?

Coding standards do not make non OO programmers into OO programmers; only
training and experience do that.  If coding standards have merit, it is that
they discourage the petty fragmentation that occurs when large organizations
coordinate the activities of diverse groups of programmers.

But you really want more than a coding standard.  The structure provided by
coding standards gives neophytes one less degree of freedom to worry about,
however pragmatics go well beyond pretty-printing standards.  Organizations
need a consistent PHILOSOPHY of design and implementation.  E.g., strong or
weak typing?  references or ptrs in interfaces?  stream I/O or stdio?  should
C++ code call our C?  vise versa?  how should ABCs be used?  should inheritance
be used as an implementation technique or as a specification technique?  what
testing strategy should be employed?  inspection strategy?  should interfaces
uniformly have a "get" and/or "set" method for each data member?  should
interfaces be designed from the outside-in or the inside-out?  should errors be
handled by try/catch/throw or return codes?  etc.

What is needed is a "pseudo standard" for detailed DESIGN.  I recommend a
three-pronged approach to achieving this standardization: training, mentoring,
and libraries.  Training provides "intense instruction," mentoring allows OO to
be caught rather than just taught, and a high quality C++ class library
provides "long term instruction."  There is a thriving commercial market for
all three kinds of "training."  Advice by organizations who have been through
the mill is consistent: Buy, Don't Build.  Buy libraries, buy training, buy
tools, buy consulting.  Companies who have attempted to become a self-taught
tool-shop as well as an application/system shop have found success difficult.

Few argue that coding standards are "ideal," or even "good," however they are
necessary in the kind of organizations/situations described above.

The following FAQs provide some basic guidance in conventions and styles.

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

Q76: Should our organization determine coding standards from our C
   experience?

No!

No matter how vast your C experience, no matter how advanced your C expertise,
being a good C programmer does not make you a good C++ programmer.  Converting
from C to C++ is more than just learning the syntax and semantics of the "++"
part of C++.  Organizations who want the promise of OOP, but who fail to put
the "OO" into OOP, are fooling themselves; the balance sheet will show their
folly.

C++ coding standards should be tempered by C++ experts.  Asking comp.lang.c++
is a start (but don't use the term "coding standard" in the question; instead
simply say, "what are the pros and cons of this technique?").  Seek out experts
who can help guide you away from pitfalls.  Get training.  Buy libraries and
see if "good" libraries pass your coding standards.  Do NOT set standards by
yourself unless you have considerable experience in C++.  Having no standard is
better than having a bad standard, since improper "official" positions "harden"
bad brain traces.  There is a thriving market for both C++ training and
libraries from which to pool expertise.

One more thing: whenever something is in demand, the potential for charlatans
increases.  Look before you leap.  Also ask for student-reviews from past
companies, since not even expertise makes someone a good communicator.
Finally, select a practitioner who can teach, not a full time teacher who has a
passing knowledge of the language/paradigm.

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

Q77: Should I declare locals in the middle of a fn or at the top?

Declare near first use.

An object is initialized (constructed) the moment it is declared.  If you don't
have enough information to initialize an object until half way down the fn, you
can either initialize it to an "empty" value at the top then "assign" it later,
or initialize it correctly half way down the fn.  It's cheaper (in runtime
performance) to get it right the first time than to build it once, tear it
down, and build it again.  Simple examples show a factor of 350% speed hit for
simple classes like "String".  Your mileage may vary; surely the overall system
degradation will be less that 300+%, but there WILL be degradation.
UNNECESSARY degradation.

A common retort to the above is: "we"ll provide "set" methods for every datum
in our objects, so the cost of construction will be spread out."  This is worse
than the performance overhead, since now you're introducing a maintenance
nightmare.  Providing "set" methods for every datum is tantamount to public
data: you've exposed your implementation technique to the world.  The only
thing you've hidden is the physical NAMES of your member objects, but the fact
that you're using a List and a String and a float (for example) is open for all
to see.  Maintenance generally consumes far more resources than run-time CPU.

Locals should be declared near their first use.  Sorry that this isn't familiar
to C experts, but "new" doesn't necessarily mean "bad."

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

Q78: What source-file-name convention is best? "foo.C"? "foo.cc"? "foo.cpp"?

If you already have a convention, use it.  If not, consult your compiler to see
what the compiler expects.  Typical answers are: ".C", ".cc", ".cpp", or
".cxx" (naturally the ".C" extension assumes a case-sensitive file system to
distinguish ".C" from ".c").

At Paradigm Shift, Inc., we use ".C" in our Makefiles even on case-insensitive
file systems (on case-insensitive file systems, we supply the compiler option
that means "assume all .c files are C++ source files"; e.g., "-Tdp" for IBM
CSet++, "-cpp" for Zortech C++, "-P" for Borland C++, etc).

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

Q79: What header-file-name convention is best? "foo.H"? "foo.hh"? "foo.hpp"?

If you already have a convention, use it.  If not, and if you don't need your
editor to distinguish between C and C++ files, simply use ".h".  Otherwise use
whatever the editor wants, such as ".H", ".hh", or ".hpp".

At Paradigm Shift, Inc., we use ".h" for both C and C++ source files (then
again, we don't create many straight C header files).

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

Q80: Are there any lint-like guidelines for C++?

Yes, there are some practices which are generally considered dangerous.
However none of these are universally "bad," since situations arise when
even the worst of these is needed:
 * a class "Fred"s assignment operator should return "*this" as an "Fred&"
   (allows chaining of assignments)
 * a class with any virtual fns ought to have a virtual destructor
 * a class with any of {destructor, assignment operator, copy constructor}
   generally needs all 3
 * a class "Fred"s copy constructor and assignment operator should have "const"
   in the parameter: respectively "Fred::Fred(const Fred&)" and
   "Fred& Fred::operator=(const Fred&)".
 * always use initialization lists for class sub-objects rather than assignment
   the performance difference for user-defined classes can be substantial (3x!)
 * many assignment operators should start by testing if "we" are "them"; e.g.,
	Fred& Fred::operator= (const Fred& fred)
	{
	  if (this == &fred) return *this;
	  //...normal assignment duties...
	  return *this;
	}
   sometimes there is no need to check, but these situations generally
   correspond to when there's no need for an explicit user-specified assignment
   op (as opposed to a compiler-synthesized assignment-op).
 * in classes that define both "+=," "+" and "=," "a+=b" and "a=a+b" should
   generally do the same thing; ditto for the other identities of builtin types
   (e.g., a+=1 and ++a; p[i] and *(p+i); etc).  This can be enforced by writing
   the binary ops using the "op=" forms; e.g.,
	Fred operator+ (const Fred& a, const Fred& b)
	{
	  Fred ans = a;
	  ans += b;
	  return ans;
	}
   This way the "constructive" binary ops don't even need to be friends.  But
   it is sometimes possible to more efficiently implement common ops (e.g., if
   class "Fred" is actually "String," and "+=" has to reallocate/copy string
   memory, it may be better to know the eventual length from the beginning).

==============================================================================
SECTION 15: Keys for Smalltalk programmers to learn C++
==============================================================================

Q81: Why does C++'s FAQ have a section on Smalltalk? Is this
   Smalltalk-bashing?

The two "major" OOPLs in the world are C++ and Smalltalk.  Due to its
popularity as the OOPL with the second largest user pool, many new C++
programmers come from a Smalltalk background.  This section answers the
questions:
 * what's different about the two languages
 * what must a Smalltalk-turned-C++ programmer know to master C++

This section does *!*NOT*!* attempt to answer the questions:
 * which language is "better"?
 * why is Smalltalk "bad"?
 * why is C++ "bad"?

Nor is it an open invitation for some Smalltalk terrorist to slash my tires
while I sleep (on those rare occasions when I have time to rest these days :-).

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

Q82: What's the difference between C++ and Smalltalk?

The most important differences are:

 * static typing vs dynamic typing?
 * must inheritance be used only for subtyping?
 * value vs reference semantics?

The first two differences are illuminated in the remainder of this section; the
third point is the subject of the section that follows.

If you're a Smalltalk programmer who wants to learn C++, you'd be very wise to
study the next three FAQs carefully.

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

Q83: What is "static typing", and how is it similar/dissimilar to Smalltalk?

Static typing says the compiler checks the type-safety of every operation
STATICALLY (at compile-time), rather than to generate code which will check
things at run-time.  For example, with static typing, the signature matching of
fn arguments is checked, and an improper match is flagged as an error by the
COMPILER, not at run-time.

In OO code, the most common "typing mismatch" is invoking a member function
against an object which isn't prepared to handle the operation.  E.g., if class
"Fred" has member fn "f()" but not "g()", and "fred" is an instance of class
"Fred", then "fred.f()" is legal and "fred.g()" is illegal.  C++ (statically
typed) catches the error at compile time, and Smalltalk (dynamically typed)
catches the error at run-time.  (Technically speaking, C++ is like Pascal
--PSEUDO statically typed-- since ptr casts and unions can be used to violate
the typing system; which reminds me: only use ptr casts and unions as often as
you use "goto"s).

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

Q84: Which is a better fit for C++: "static typing" or "dynamic typing"?

If you want to use C++ most effectively, use it as a statically typed language.

C++ is flexible enough that you can (via ptr casts, unions, and #defines) make
it "look" like Smalltalk.  But don't.  Which reminds me: try to avoid #define.

There are places where ptr casts and unions are necessary and even wholesome,
but they should be used carefully and sparingly.  A ptr cast tells the compiler
to believe you.  An incorrect ptr cast might corrupt your heap, scribble into
memory owned by other objects, call nonexistent methods, and cause general
failures.  It's not a pretty sight.  If you avoid these and related constructs,
you can make your C++ code both safer and faster, since anything that can be
checked at compile time is something that doesn't have to be done at run-time.

Even if you're in love with dynamic typing, please avoid it in C++, or else
please consider using another language that better supports your desire to
defer typing decisions to run-time.  C++ performs 100% of its type checking at
compile time; it has NO built-in mechanism to do ANY type checking at run-time.
If you use C++ as a dynamically typed OOPL, your life is in your own hands.

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

Q85: How can you tell if you have a dynamically typed C++ class library?

Hint #1: when everything is derived from a single root class, usually "Object."
Hint #2: when the container classes (List, Stack, Set, etc) are non-templates.
Hint #3: when the container classes (List, Stack, Set, etc) insert/extract
elements as pointers to "Object" (you can put an Apple into such a container,
but when you get it out, the compiler only knows that it is derived from
Object, so you have to use a pointer cast to convert it back to an Apple*; and
you better pray a lot that it really IS an Apple, cause your blood is on your
own head).

You can make the pointer cast "safe" by using "dynamic_cast" (see earlier), but
this dynamic testing is just that: dynamic.  This coding style is the essence
of dynamic typing in C++.  You call a function that says "convert this Object
into an Apple or give me NULL if its not an Apple," and you've got dynamic
typing: you don't know what will happen until run-time.

When you use with templates to implement your containers, the C++ compiler can
statically validate 99% of an application's typing information (the figure
"99%" is apocryphal; some claim they always get 100%, those who need
persistence get something less than 100% static type checking).  The point is:
C++ gets genericity from templates, not from inheritance.

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

Q86: How do you use inheritance in C++, and is that different from Smalltalk?

Some people believe that the purpose of inheritance is code reuse.  In C++,
this is wrong.  Stated plainly, "inheritance is not 'for' code reuse."

The purpose of inheritance in C++ is to express interface compliance
(subtyping), not to get code reuse.  In C++, code reuse usually comes via
composition rather than via inheritance.  In other words, inheritance is mainly
a specification technique rather than an implementation technique.

This is a major difference with Smalltalk, where there is only one form of
inheritance (C++ provides "private" inheritance to mean "share the code but
don't conform to the interface", and "public" inheritance to mean "kind-of").
The Smalltalk language proper (as opposed to coding practice) allows you to
have the EFFECT of "hiding" an inherited method by providing an override that
calls the "does not understand" method.  Furthermore Smalltalk allows a
conceptual "is-a" relationship to exist APART from the subclassing hierarchy
(subtypes don't have to be subclasses; e.g., you can make something that is-a
Stack yet doesn't inherit from class Stack).

In contrast, C++ is more restrictive about inheritance: there's no way to make
a "conceptual is-a" relationship without using inheritance (the C++ work-around
is to separate interface from implementation via ABCs).  The C++ compiler
exploits the added semantic information associated with public inheritance to
provide static typing.

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

Q87: What are the practical consequences of diffs in Smalltalk/C++
   inheritance?

Smalltalk lets you make a subtype that isn't a subclass, and allows you to make
a subclass that isn't a subtype.  This allows Smalltalk programmers to be very
carefree in putting data (bits, representation, data structure) into a class
(e.g., you might put a linked list into a Stack class).  After all, if someone
wants an array-based-Stack, they don't have to inherit from Stack; they could
inherit such a class from Array if desired, even though an ArrayBasedStack is
NOT a kind-of Array!

In C++, you can't be nearly as carefree.  Only mechanism (method code), but not
representation (data bits) can be overridden in subclasses.  Therefore you're
usually better off NOT putting the data structure in a class.  This leads to a
stronger reliance on Abstract Base Classes (ABCs).

I like to think of the difference between an ATV and a Maseratti.  An ATV (all
terrain vehicle) is more fun, since you can "play around" by driving through
fields, streams, sidewalks, and the like.  A Maseratti, on the other hand, gets
you there faster, but it forces you to stay on the road.  My advice to C++
programmers is simple: stay on the road.  Even if you're one of those people
who like the "expressive freedom" to drive through the bushes, don't do it in
C++; it's not a good fit.

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

Q88: Do you need to learn a "pure" OOPL before you learn C++?

No (in fact, doing so might actually hurt you).

(Note that Smalltalk is a "pure" OOPL, and C++ is a "hybrid" OOPL).  Before
reading this, please read the previous FAQs on the difference between C++ and
Smalltalk.

The "purity" of the OOPL doesn't make the transition to C++ any easier.  In
fact, the typical use of dynamic typing and non-subtyping inheritance can make
it even harder for Smalltalk programmers to learn C++.  Paradigm Shift, Inc.,
has taught OO technology to literally thousands of people, and we have noticed
that people who want to learn C++ from a Smalltalk background usually have just
as hard a time as those who've never seen inheritance before.  In fact, those
with extensive experience with a dynamically typed OOPL (usually but not always
Smalltalk) might even have a HARDER time, since it's harder to UNLEARN habits
than it is to learn the statically typed way from the beginning.

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

Q89: What is the NIHCL?  Where can I get it?

NIHCL stands for "national-institute-of-health's-class-library."
it can be acquired via anonymous ftp from [128.231.128.7]
in the file pub/nihcl-3.0.tar.Z

NIHCL (some people pronounce it "N-I-H-C-L," others pronounce it like "nickel")
is a C++ translation of the Smalltalk class library.  There are some ways where
NIHCL's use of dynamic typing helps (e.g., persistent objects).  There are also
places where its use of dynamic typing creates tension with the static typing
of the C++ language.

See previous FAQs on Smalltalk for more.

==============================================================================
SECTION 16: Reference and value semantics
==============================================================================

Q90: What is value and/or reference semantics, and which is best in C++?

With reference semantics, assignment is a pointer-copy (i.e., a REFERENCE).
Value (or "copy") semantics mean assignment copies the value, not just the
pointer.  C++ gives you the choice: use the assignment operator to copy the
value (copy/value semantics), or use a ptr-copy to copy a pointer (reference
semantics).  C++ allows you to override the assignment operator to do anything
your heart desires, however the default (and most common) choice is to copy the
VALUE.

Pros of reference semantics: flexibility and dynamic binding (you get dynamic
binding in C++ only when you pass by ptr or pass by ref, not when you pass by
value).

Pros of value semantics: speed.  "Speed" seems like an odd benefit to for a
feature that requires an object (vs a ptr) to be copied, but the fact of the
matter is that one usually accesses an object more than one copies the object,
so the cost of the occasional copies is (usually) more than offset by the
benefit of having an actual object rather than a ptr to an object.

There are three cases when you have an actual object as opposed to a pointer to
an object: local vars, global/static vars, and fully contained member objects
in a class.  The most important of these is the last ("composition").

More info about copy-vs-reference semantics is given in the next FAQs.  Please
read them all to get a balanced perspective.  The first few have intentionally
been slanted toward value semantics, so if you only read the first few of the
following FAQs, you'll get a warped perspective.

Assignment has other issues (e.g., shallow vs deep copy) which are not covered
here.

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

Q91: What is "virtual data," and how-can / why-would I use it in C++?

Virtual data allows a derived class to change the exact class of a base class's
member object.  Virtual data isn't strictly "supported" by C++, however it
can be simulated in C++.  It ain't pretty, but it works.

To simulate virtual data in C++, the base class must have a pointer to the
member object, and the derived class must provide a "new" object to be pointed
to by the base class's pointer.  The base class would also have one or more
normal constructors that provide their own referrent (again via "new"), and the
base class's destructor would "delete" the referent.

For example, class "Stack" might have an Array member object (using a pointer),
and derived class "StretchableStack" might override the base class member data
from "Array" to "StretchableArray".  For this to work, StretchableArray would
have to inherit from Array, so Stack would have an "Array*".  Stack's normal
constructors would initialize this "Array*" with a "new Array", but Stack would
also have a (possibly "protected:") constructor that would accept an "Array*"
from a derived class.  StretchableArray's constructor would provide a "new
StretchableArray" to this special constructor.

Pros:
 * Easier implementation of StretchableStack (most of the code is inherited).
 * Users can pass a StretchableStack as a kind-of Stack.

Cons:
 * Adds an extra layer of indirection to access the Array.
 * Adds some extra freestore allocation overhead (both new and delete).
 * Adds some extra dynamic binding overhead (reason given in next FAQ).

In other words, we succeeded at making OUR job easier as the implementor of
StretchableStack, but all our users pay for it.  Unfortunately the extra
overhead was imposed on both users of StretchableStack AND on users of Stack.

See the FAQ after the next to find out how much the users "pay."  Also: PLEASE
read the few FAQs that follow the next one too (YOU WILL NOT GET A BALANCED
PERSPECTIVE WITHOUT THE OTHERS).

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

Q92: What's the difference between virtual data and dynamic data?

The easiest way to see the distinction is by an analogy with "virtual fns":
A virtual member fn means the declaration (signature) must stay the same in
subclasses, but the defn (body) can be overridden.  The overriddenness of an
inherited member fn is a static property of the subclass; it doesn't change
dynamically throughout the life of any particular object, nor is it possible
for distinct objects of the subclass to have distinct defns of the member fn.

Now go back and re-read the previous paragraph, but make these substitutions:
 * "member fn" --> "member object"
 * "signature" --> "type"
 * "body"      --> "exact class'
After this, you'll have a working definition of virtual data.

Another way to look at this is to distinguish "per-object" member functions
from "dynamic" member functions.  A "per-object" member fn is a member fn that
is potentially different in any given instance of an object, and could be
implemented by burying a function ptr in the object; this pointer could be
"const", since the pointer will never be changed throughout the object's life.
A "dynamic" member fn is a member fn that will change dynamically over time;
this could also be implemented by a function ptr, but the fn ptr would not be
const.

Extending the analogy, this gives us three distinct concepts for data members:
 * virtual data: the defn ("class") of the member object is overridable in
   subclasses provided its declaration ("type") remains the same, and this
   overriddenness is a static property of the subclass.
 * per-object-data: any given object of a class can instantiate a different
   conformal (same type) member object upon initialization (usually a "wrapper"
   object), and the exact class of the member object is a static property of
   the object that wraps it.
 * dynamic-data: the member object's exact class can change dynamically over
   time.

The reason they all look so much the same is that none of this is "supported"
in C++.  It's all merely "allowed," and in this case, the mechanism for faking
each of these is the same: a ptr to a (probably abstract) base class.  In a
language that made these "first class" abstraction mechanisms, the difference
would be more striking, since they'd each have a different syntactic variant.

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

Q93: Should I normally use pointers to freestore allocated objects for my data
   members, or should I use "composition"?

Composition.

Your member objects should normally be "contained" in the composite object (but
not always; "wrapper" objects are a good example of where you want a ptr/ref;
also the N-to-1-uses-a relationship needs something like a ptr/ref).

There are three reasons why fully contained member objects ("composition") has
better performance than ptrs to freestore-allocated member objects:

 * Extra layer to indirection every time you need to access the member object.
 * Extra freestore allocations ("new" in constructor, "delete" in destructor).
 * Extra dynamic binding (reason given below).

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

Q94: What are relative costs of the 3 performance hits associated with
   allocating member objects from the freestore?

The three performance hits are enumerated in the previous FAQ:
 * By itself, an extra layer of indirection is small potatoes.
 * Freestore allocations can be a performance issue (the performance of the
   typical implementation of malloc degrades when there are many allocations;
   OO s/w can easily become "freestore bound" unless you're careful).
 * The extra dynamic binding comes from having a ptr rather than an object.
   Whenever the C++ compiler can know an object's EXACT class, virtual fn
   calls can be STATICALLY bound, which allows inlining.  Inlining allows
   zillions (would you believe half a dozen :-) optimization opportunities
   such as procedural integration, register lifetime issues, etc.  The C++
   compiler can know an object's exact class in three circumstances: local
   variables, global/static variables, and fully-contained member objects.

Thus fully-contained member objects allow significant optimizations that
wouldn't be possible under the "member objects-by-ptr" approach.  This is the
main reason that languages which enforce reference-semantics have "inherent"
performance challenges.

NOTE: PLEASE READ THE NEXT THREE FAQs TO GET A BALANCED PERSPECTIVE!

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

Q95: Are "inline virtual" member fns ever actually "inlined"?

Yes but...

A virtual call via a ptr or ref is always resolved dynamically, which can never
be inlined.  Reason: the compiler can't know which actual code to call until
run-time (i.e., dynamically), since the code may be from a derived class that
was created after the caller was compiled.

Therefore the only time an inline virtual call can be inlined is when the
compiler knows the "exact class" of the object which is the target of the
virtual function call.  This can only happen when the compiler has an actual
object rather than a pointer or reference to an object.  I.e., either with a
local object, a global/static object, or a fully contained object inside a
composite.

Note that the difference between inlining and non-inlining is normally MUCH
more significant than the difference between a regular fn call and a virtual fn
call.  For example, the difference between a regular fn call and a virtual fn
call is often just two extra memory references, but the difference between an
inline function and a non-inline function can be as much as an order of
magnitude (for zillions of calls to insignificant member fns, loss of inlining
virtual fns can result in 25X speed degradation!  [Doug Lea, "Customization in
C++," proc Usenix C++ 1990]).

A practical consequence of this insight: don't get bogged down in the endless
debates (or sales tactics!) of compiler/language vendors who compare the cost
of a virtual function call on their language/compiler with the same on another
language/compiler.  Such comparisons are largely meaningless when compared with
the ability of the language/compiler to "inline expand" member function calls.
I.e., many language implementation vendors make a big stink about how good
their dispatch strategy is, but if these implementations don't INLINE method
calls, the overall system performance would be poor, since it is inlining --NOT
dispatching-- that has the greatest performance impact.

NOTE: PLEASE READ THE NEXT TWO FAQs TO SEE THE OTHER SIDE OF THIS COIN!

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

Q96: Sounds like I should never use reference semantics, right?

Wrong.

Reference semantics are A Good Thing.  We can't live without pointers.  We just
don't want our s/w to be One Gigantic Rats Nest Of Pointers.  In C++, you can
pick and choose where you want reference semantics (ptrs/refs) and where you'd
like value semantics (where objects physically contain other objects etc).  In
a large system, there should be a balance.  However if you implement absolutely
EVERYTHING as a pointer, you'll get enormous speed hits.

Objects near the problem skin are larger than higher level objects.  The
IDENTITY of these "problem space" abstractions is usually more important than
their "value."  Thus reference semantics should be used for problem-space
objects.

Note that these problem space objects are normally at a higher level of
abstraction than the solution space objects, so the problem space objects
normally have a relatively lower frequency of interaction.  Therefore C++ gives
us an IDEAL situation: we choose reference semantics for objects that need
unique identity or that are too large to copy, and we can choose value
semantics for the others.  Thus the highest frequency objects will end up with
value semantics, since we install flexibility only where it doesn't hurt us,
and we install performance where we need it most!

These are some of the many issues the come into play with real OO design.
OO/C++ mastery takes time and high quality training.  If you want a powerful
tool, you've got to invest.

           <<<<DON'T STOP NOW!  READ THE NEXT FAQ TOO!!>>>>

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

Q97: Does the poor performance of ref semantics mean I should pass-by-value?

Nope.

The previous FAQ were talking about MEMBER OBJECTS, not parameters.  Generally,
objects that are part of an inheritance hierarchy should be passed by ref or by
ptr, NOT by value, since only then do you get the (desired) dynamic binding
(pass-by-value doesn't mix with inheritance, since larger subclass objects get
"sliced" when passed by value as a base class object).

Unless compelling reasons are given to the contrary, member objects should be
by value and parameters should be by reference.  The discussion in the previous
few FAQs indicates some of the "compelling reasons" for when member objects
should be by reference.

--
Marshall Cline
--
Marshall P. Cline, Ph.D. / Paradigm Shift Inc / PO Box 5108 / Potsdam NY 13676
cline@sun.soe.clarkson.edu / 315-353-6100 / FAX: 315-353-6110

From ankh.iia.org!uunet!news.mathworks.com!news.kei.com!ub!library.erc.clarkson.edu!sun.soe.clarkson.edu!cline Sun Dec 18 23:53:22 1994
Path: ankh.iia.org!uunet!news.mathworks.com!news.kei.com!ub!library.erc.clarkson.edu!sun.soe.clarkson.edu!cline
From: cline@sun.soe.clarkson.edu (Marshall Cline)
Newsgroups: comp.lang.c++
Subject: C++ FAQ: posting #3/4
Followup-To: comp.lang.c++
Date: 13 Dec 1994 05:57:53 GMT
Organization: Paradigm Shift, Inc (training/consulting/OOD/OOP/C++)
Lines: 639
Sender: cline@sun.soe.clarkson.edu
Distribution: world
Expires: +1 month
Message-ID: <3cjd51$gkf@library.erc.clarkson.edu>
Reply-To: cline@parashift.com (Marshall Cline)
NNTP-Posting-Host: sun.soe.clarkson.edu
Summary: Please read this before posting to comp.lang.c++

comp.lang.c++ Frequently Asked Questions list (with answers, fortunately).
Copyright (C) 1991-94 Marshall P. Cline, Ph.D.
Posting 3 of 4.
Posting #1 explains copying permissions, (no)warranty, table-of-contents, etc

==============================================================================
SECTION 14: Style guidelines
==============================================================================

Q74: What are some good C++ coding standards?

Thank you for reading this answer rather than just trying to set your own
coding standards.

But please don't ask this question on comp.lang.c++.  Nearly every software
engineer has, at some point, felt that coding standards are or can be used as a
"power play."  Furthermore some attempts to set C++ coding standards have been
made by those unfamiliar with the language and/or paradigm, so the standards
end up being based on what WAS the state-of-the-art when the standards setters
where writing code.  Such impositions generate an attitude of mistrust for
coding standards.

Obviously anyone who asks this question on comp.lang.c++ wants to be trained so
they DON'T run off on their own ignorance, but nonetheless the answers tend to
generate more heat than light.

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

Q75: Are coding standards necessary?  Are they sufficient?

Coding standards do not make non OO programmers into OO programmers; only
training and experience do that.  If coding standards have merit, it is that
they discourage the petty fragmentation that occurs when large organizations
coordinate the activities of diverse groups of programmers.

But you really want more than a coding standard.  The structure provided by
coding standards gives neophytes one less degree of freedom to worry about,
however pragmatics go well beyond pretty-printing standards.  Organizations
need a consistent PHILOSOPHY of design and implementation.  E.g., strong or
weak typing?  references or ptrs in interfaces?  stream I/O or stdio?  should
C++ code call our C?  vise versa?  how should ABCs be used?  should inheritance
be used as an implementation technique or as a specification technique?  what
testing strategy should be employed?  inspection strategy?  should interfaces
uniformly have a "get" and/or "set" method for each data member?  should
interfaces be designed from the outside-in or the inside-out?  should errors be
handled by try/catch/throw or return codes?  etc.

What is needed is a "pseudo standard" for detailed DESIGN.  I recommend a
three-pronged approach to achieving this standardization: training, mentoring,
and libraries.  Training provides "intense instruction," mentoring allows OO to
be caught rather than just taught, and a high quality C++ class library
provides "long term instruction."  There is a thriving commercial market for
all three kinds of "training."  Advice by organizations who have been through
the mill is consistent: Buy, Don't Build.  Buy libraries, buy training, buy
tools, buy consulting.  Companies who have attempted to become a self-taught
tool-shop as well as an application/system shop have found success difficult.

Few argue that coding standards are "ideal," or even "good," however they are
necessary in the kind of organizations/situations described above.

The following FAQs provide some basic guidance in conventions and styles.

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

Q76: Should our organization determine coding standards from our C
   experience?

No!

No matter how vast your C experience, no matter how advanced your C expertise,
being a good C programmer does not make you a good C++ programmer.  Converting
from C to C++ is more than just learning the syntax and semantics of the "++"
part of C++.  Organizations who want the promise of OOP, but who fail to put
the "OO" into OOP, are fooling themselves; the balance sheet will show their
folly.

C++ coding standards should be tempered by C++ experts.  Asking comp.lang.c++
is a start (but don't use the term "coding standard" in the question; instead
simply say, "what are the pros and cons of this technique?").  Seek out experts
who can help guide you away from pitfalls.  Get training.  Buy libraries and
see if "good" libraries pass your coding standards.  Do NOT set standards by
yourself unless you have considerable experience in C++.  Having no standard is
better than having a bad standard, since improper "official" positions "harden"
bad brain traces.  There is a thriving market for both C++ training and
libraries from which to pool expertise.

One more thing: whenever something is in demand, the potential for charlatans
increases.  Look before you leap.  Also ask for student-reviews from past
companies, since not even expertise makes someone a good communicator.
Finally, select a practitioner who can teach, not a full time teacher who has a
passing knowledge of the language/paradigm.

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

Q77: Should I declare locals in the middle of a fn or at the top?

Declare near first use.

An object is initialized (constructed) the moment it is declared.  If you don't
have enough information to initialize an object until half way down the fn, you
can either initialize it to an "empty" value at the top then "assign" it later,
or initialize it correctly half way down the fn.  It's cheaper (in runtime
performance) to get it right the first time than to build it once, tear it
down, and build it again.  Simple examples show a factor of 350% speed hit for
simple classes like "String".  Your mileage may vary; surely the overall system
degradation will be less that 300+%, but there WILL be degradation.
UNNECESSARY degradation.

A common retort to the above is: "we"ll provide "set" methods for every datum
in our objects, so the cost of construction will be spread out."  This is worse
than the performance overhead, since now you're introducing a maintenance
nightmare.  Providing "set" methods for every datum is tantamount to public
data: you've exposed your implementation technique to the world.  The only
thing you've hidden is the physical NAMES of your member objects, but the fact
that you're using a List and a String and a float (for example) is open for all
to see.  Maintenance generally consumes far more resources than run-time CPU.

Locals should be declared near their first use.  Sorry that this isn't familiar
to C experts, but "new" doesn't necessarily mean "bad."

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

Q78: What source-file-name convention is best? "foo.C"? "foo.cc"? "foo.cpp"?

If you already have a convention, use it.  If not, consult your compiler to see
what the compiler expects.  Typical answers are: ".C", ".cc", ".cpp", or
".cxx" (naturally the ".C" extension assumes a case-sensitive file system to
distinguish ".C" from ".c").

At Paradigm Shift, Inc., we use ".C" in our Makefiles even on case-insensitive
file systems (on case-insensitive file systems, we supply the compiler option
that means "assume all .c files are C++ source files"; e.g., "-Tdp" for IBM
CSet++, "-cpp" for Zortech C++, "-P" for Borland C++, etc).

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

Q79: What header-file-name convention is best? "foo.H"? "foo.hh"? "foo.hpp"?

If you already have a convention, use it.  If not, and if you don't need your
editor to distinguish between C and C++ files, simply use ".h".  Otherwise use
whatever the editor wants, such as ".H", ".hh", or ".hpp".

At Paradigm Shift, Inc., we use ".h" for both C and C++ source files (then
again, we don't create many straight C header files).

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

Q80: Are there any lint-like guidelines for C++?

Yes, there are some practices which are generally considered dangerous.
However none of these are universally "bad," since situations arise when
even the worst of these is needed:
 * a class "Fred"s assignment operator should return "*this" as an "Fred&"
   (allows chaining of assignments)
 * a class with any virtual fns ought to have a virtual destructor
 * a class with any of {destructor, assignment operator, copy constructor}
   generally needs all 3
 * a class "Fred"s copy constructor and assignment operator should have "const"
   in the parameter: respectively "Fred::Fred(const Fred&)" and
   "Fred& Fred::operator=(const Fred&)".
 * always use initialization lists for class sub-objects rather than assignment
   the performance difference for user-defined classes can be substantial (3x!)
 * many assignment operators should start by testing if "we" are "them"; e.g.,
	Fred& Fred::operator= (const Fred& fred)
	{
	  if (this == &fred) return *this;
	  //...normal assignment duties...
	  return *this;
	}
   sometimes there is no need to check, but these situations generally
   correspond to when there's no need for an explicit user-specified assignment
   op (as opposed to a compiler-synthesized assignment-op).
 * in classes that define both "+=," "+" and "=," "a+=b" and "a=a+b" should
   generally do the same thing; ditto for the other identities of builtin types
   (e.g., a+=1 and ++a; p[i] and *(p+i); etc).  This can be enforced by writing
   the binary ops using the "op=" forms; e.g.,
	Fred operator+ (const Fred& a, const Fred& b)
	{
	  Fred ans = a;
	  ans += b;
	  return ans;
	}
   This way the "constructive" binary ops don't even need to be friends.  But
   it is sometimes possible to more efficiently implement common ops (e.g., if
   class "Fred" is actually "String," and "+=" has to reallocate/copy string
   memory, it may be better to know the eventual length from the beginning).

==============================================================================
SECTION 15: Keys for Smalltalk programmers to learn C++
==============================================================================

Q81: Why does C++'s FAQ have a section on Smalltalk? Is this
   Smalltalk-bashing?

The two "major" OOPLs in the world are C++ and Smalltalk.  Due to its
popularity as the OOPL with the second largest user pool, many new C++
programmers come from a Smalltalk background.  This section answers the
questions:
 * what's different about the two languages
 * what must a Smalltalk-turned-C++ programmer know to master C++

This section does *!*NOT*!* attempt to answer the questions:
 * which language is "better"?
 * why is Smalltalk "bad"?
 * why is C++ "bad"?

Nor is it an open invitation for some Smalltalk terrorist to slash my tires
while I sleep (on those rare occasions when I have time to rest these days :-).

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

Q82: What's the difference between C++ and Smalltalk?

The most important differences are:

 * static typing vs dynamic typing?
 * must inheritance be used for subtyping only?
 * value vs reference semantics?

The first two differences are illuminated in the remainder of this section; the
third point is the subject of the section that follows.

If you're a Smalltalk programmer who wants to learn C++, you'd be very wise to
study the next three FAQs carefully.

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

Q83: What is "static typing", and how is it similar/dissimilar to Smalltalk?

Static typing says the compiler checks the type-safety of every operation
STATICALLY (at compile-time), rather than to generate code which will check
things at run-time.  For example, with static typing, the signature matching of
fn arguments is checked, and an improper match is flagged as an error by the
COMPILER, not at run-time.

In OO code, the most common "typing mismatch" is invoking a member function
against an object which isn't prepared to handle the operation.  E.g., if class
"Fred" has member fn "f()" but not "g()", and "fred" is an instance of class
"Fred", then "fred.f()" is legal and "fred.g()" is illegal.  C++ (statically
typed) catches the error at compile time, and Smalltalk (dynamically typed)
catches the error at run-time.  (Technically speaking, C++ is like Pascal
--PSEUDO statically typed-- since ptr casts and unions can be used to violate
the typing system; which reminds me: only use ptr casts and unions as often as
you use "goto"s).

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

Q84: Which is a better fit for C++: "static typing" or "dynamic typing"?

If you want to use C++ most effectively, use it as a statically typed language.

C++ is flexible enough that you can (via ptr casts, unions, and #defines) make
it "look" like Smalltalk.  But don't.  Which reminds me: try to avoid #define.

There are places where ptr casts and unions are necessary and even wholesome,
but they should be used carefully and sparingly.  A ptr cast tells the compiler
to believe you.  An incorrect ptr cast might corrupt your heap, scribble into
memory owned by other objects, call nonexistent methods, and cause general
failures.  It's not a pretty sight.  If you avoid these and related constructs,
you can make your C++ code both safer and faster, since anything that can be
checked at compile time is something that doesn't have to be done at run-time.

Even if you're in love with dynamic typing, please avoid it in C++, or else
please consider using another language that better supports your desire to
defer typing decisions to run-time.  C++ performs 100% of its type checking at
compile time; it has NO built-in mechanism to do ANY type checking at run-time.
If you use C++ as a dynamically typed OOPL, your life is in your own hands.

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

Q85: How can you tell if you have a dynamically typed C++ class library?

Hint #1: when everything is derived from a single root class, usually "Object."
Hint #2: when the container classes (List, Stack, Set, etc) are non-templates.
Hint #3: when the container classes (List, Stack, Set, etc) insert/extract
elements as pointers to "Object" (you can put an Apple into such a container,
but when you get it out, the compiler knows only that it is derived from
Object, so you have to use a pointer cast to convert it back to an Apple*; and
you better pray a lot that it really IS an Apple, cause your blood is on your
own head).

You can make the pointer cast "safe" by using "dynamic_cast" (see earlier), but
this dynamic testing is just that: dynamic.  This coding style is the essence
of dynamic typing in C++.  You call a function that says "convert this Object
into an Apple or give me NULL if its not an Apple," and you've got dynamic
typing: you don't know what will happen until run-time.

When you use with templates to implement your containers, the C++ compiler can
statically validate 99% of an application's typing information (the figure
"99%" is apocryphal; some claim they always get 100%, those who need
persistence get something less than 100% static type checking).  The point is:
C++ gets genericity from templates, not from inheritance.

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

Q86: How do you use inheritance in C++, and is that different from Smalltalk?

Some people believe that the purpose of inheritance is code reuse.  In C++,
this is wrong.  Stated plainly, "inheritance is not 'for' code reuse."

The purpose of inheritance in C++ is to express interface compliance
(subtyping), not to get code reuse.  In C++, code reuse usually comes via
composition rather than via inheritance.  In other words, inheritance is mainly
a specification technique rather than an implementation technique.

This is a major difference with Smalltalk, where there is only one form of
inheritance (C++ provides "private" inheritance to mean "share the code but
don't conform to the interface", and "public" inheritance to mean "kind-of").
The Smalltalk language proper (as opposed to coding practice) allows you to
have the EFFECT of "hiding" an inherited method by providing an override that
calls the "does not understand" method.  Furthermore Smalltalk allows a
conceptual "is-a" relationship to exist APART from the subclassing hierarchy
(subtypes don't have to be subclasses; e.g., you can make something that is-a
Stack yet doesn't inherit from class Stack).

In contrast, C++ is more restrictive about inheritance: there's no way to make
a "conceptual is-a" relationship without using inheritance (the C++ work-around
is to separate interface from implementation via ABCs).  The C++ compiler
exploits the added semantic information associated with public inheritance to
provide static typing.

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

Q87: What are the practical consequences of diffs in Smalltalk/C++
   inheritance?

Smalltalk lets you make a subtype that isn't a subclass, and allows you to make
a subclass that isn't a subtype.  This allows Smalltalk programmers to be very
carefree in putting data (bits, representation, data structure) into a class
(e.g., you might put a linked list into a Stack class).  After all, if someone
wants an array-based-Stack, they don't have to inherit from Stack; they could
inherit such a class from Array if desired, even though an ArrayBasedStack is
NOT a kind-of Array!

In C++, you can't be nearly as carefree.  Only mechanism (method code), but not
representation (data bits) can be overridden in subclasses.  Therefore you're
usually better off NOT putting the data structure in a class.  This leads to a
stronger reliance on Abstract Base Classes (ABCs).

I like to think of the difference between an ATV and a Maseratti.  An ATV (all
terrain vehicle) is more fun, since you can "play around" by driving through
fields, streams, sidewalks, and the like.  A Maseratti, on the other hand, gets
you there faster, but it forces you to stay on the road.  My advice to C++
programmers is simple: stay on the road.  Even if you're one of those people
who like the "expressive freedom" to drive through the bushes, don't do it in
C++; it's not a good fit.

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

Q88: Do you need to learn a "pure" OOPL before you learn C++?

No (in fact, doing so might actually hurt you).

(Note that Smalltalk is a "pure" OOPL, and C++ is a "hybrid" OOPL).  Before
reading this, please read the previous FAQs on the difference between C++ and
Smalltalk.

The "purity" of the OOPL doesn't make the transition to C++ any easier.  In
fact, the typical use of dynamic typing and non-subtyping inheritance can make
it even harder for Smalltalk programmers to learn C++.  Paradigm Shift, Inc.,
has taught OO technology to literally thousands of people, and we have noticed
that people who want to learn C++ from a Smalltalk background usually have just
as hard a time as those who've never seen inheritance before.  In fact, those
with extensive experience with a dynamically typed OOPL (usually but not always
Smalltalk) might even have a HARDER time, since it's harder to UNLEARN habits
than it is to learn the statically typed way from the beginning.

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

Q89: What is the NIHCL?  Where can I get it?

NIHCL stands for "national-institute-of-health's-class-library."
it can be acquired via anonymous ftp from [128.231.128.7]
in the file pub/nihcl-3.0.tar.Z

NIHCL (some people pronounce it "N-I-H-C-L," others pronounce it like "nickel")
is a C++ translation of the Smalltalk class library.  There are some ways where
NIHCL's use of dynamic typing helps (e.g., persistent objects).  There are also
places where its use of dynamic typing creates tension with the static typing
of the C++ language.

See previous FAQs on Smalltalk for more.

==============================================================================
SECTION 16: Reference and value semantics
==============================================================================

Q90: What is value and/or reference semantics, and which is best in C++?

With reference semantics, assignment is a pointer-copy (i.e., a REFERENCE).
Value (or "copy") semantics mean assignment copies the value, not just the
pointer.  C++ gives you the choice: use the assignment operator to copy the
value (copy/value semantics), or use a ptr-copy to copy a pointer (reference
semantics).  C++ allows you to override the assignment operator to do anything
your heart desires, however the default (and most common) choice is to copy the
VALUE.

Pros of reference semantics: flexibility and dynamic binding (you get dynamic
binding in C++ only when you pass by ptr or pass by ref, not when you pass by
value).

Pros of value semantics: speed.  "Speed" seems like an odd benefit to for a
feature that requires an object (vs a ptr) to be copied, but the fact of the
matter is that one usually accesses an object more than one copies the object,
so the cost of the occasional copies is (usually) more than offset by the
benefit of having an actual object rather than a ptr to an object.

There are three cases when you have an actual object as opposed to a pointer to
an object: local vars, global/static vars, and fully contained member objects
in a class.  The most important of these is the last ("composition").

More info about copy-vs-reference semantics is given in the next FAQs.  Please
read them all to get a balanced perspective.  The first few have intentionally
been slanted toward value semantics, so if you only read the first few of the
following FAQs, you'll get a warped perspective.

Assignment has other issues (e.g., shallow vs deep copy) which are not covered
here.

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

Q91: What is "virtual data," and how-can / why-would I use it in C++?

Virtual data allows a derived class to change the exact class of a base class's
member object.  Virtual data isn't strictly "supported" by C++, however it
can be simulated in C++.  It ain't pretty, but it works.

To simulate virtual data in C++, the base class must have a pointer to the
member object, and the derived class must provide a "new" object to be pointed
to by the base class's pointer.  The base class would also have one or more
normal constructors that provide their own referrent (again via "new"), and the
base class's destructor would "delete" the referent.

For example, class "Stack" might have an Array member object (using a pointer),
and derived class "StretchableStack" might override the base class member data
from "Array" to "StretchableArray".  For this to work, StretchableArray would
have to inherit from Array, so Stack would have an "Array*".  Stack's normal
constructors would initialize this "Array*" with a "new Array", but Stack would
also have a (possibly "protected:") constructor that would accept an "Array*"
from a derived class.  StretchableArray's constructor would provide a "new
StretchableArray" to this special constructor.

Pros:
 * Easier implementation of StretchableStack (most of the code is inherited).
 * Users can pass a StretchableStack as a kind-of Stack.

Cons:
 * Adds an extra layer of indirection to access the Array.
 * Adds some extra freestore allocation overhead (both new and delete).
 * Adds some extra dynamic binding overhead (reason given in next FAQ).

In other words, we succeeded at making OUR job easier as the implementor of
StretchableStack, but all our users pay for it.  Unfortunately the extra
overhead was imposed on both users of StretchableStack AND on users of Stack.

See the FAQ after the next to find out how much the users "pay."  Also: PLEASE
read the few FAQs that follow the next one too (YOU WILL NOT GET A BALANCED
PERSPECTIVE WITHOUT THE OTHERS).

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

Q92: What's the difference between virtual data and dynamic data?

The easiest way to see the distinction is by an analogy with "virtual fns":
A virtual member fn means the declaration (signature) must stay the same in
subclasses, but the defn (body) can be overridden.  The overriddenness of an
inherited member fn is a static property of the subclass; it doesn't change
dynamically throughout the life of any particular object, nor is it possible
for distinct objects of the subclass to have distinct defns of the member fn.

Now go back and re-read the previous paragraph, but make these substitutions:
 * "member fn" --> "member object"
 * "signature" --> "type"
 * "body"      --> "exact class'
After this, you'll have a working definition of virtual data.

Another way to look at this is to distinguish "per-object" member functions
from "dynamic" member functions.  A "per-object" member fn is a member fn that
is potentially different in any given instance of an object, and could be
implemented by burying a function ptr in the object; this pointer could be
"const", since the pointer will never be changed throughout the object's life.
A "dynamic" member fn is a member fn that will change dynamically over time;
this could also be implemented by a function ptr, but the fn ptr would not be
const.

Extending the analogy, this gives us three distinct concepts for data members:
 * virtual data: the defn ("class") of the member object is overridable in
   subclasses provided its declaration ("type") remains the same, and this
   overriddenness is a static property of the subclass.
 * per-object-data: any given object of a class can instantiate a different
   conformal (same type) member object upon initialization (usually a "wrapper"
   object), and the exact class of the member object is a static property of
   the object that wraps it.
 * dynamic-data: the member object's exact class can change dynamically over
   time.

The reason they all look so much the same is that none of this is "supported"
in C++.  It's all merely "allowed," and in this case, the mechanism for faking
each of these is the same: a ptr to a (probably abstract) base class.  In a
language that made these "first class" abstraction mechanisms, the difference
would be more striking, since they'd each have a different syntactic variant.

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

Q93: Should I normally use pointers to freestore allocated objects for my data
   members, or should I use "composition"?

Composition.

Your member objects should normally be "contained" in the composite object (but
not always; "wrapper" objects are a good example of where you want a ptr/ref;
also the N-to-1-uses-a relationship needs something like a ptr/ref).

There are three reasons why fully contained member objects ("composition") has
better performance than ptrs to freestore-allocated member objects:

 * Extra layer to indirection every time you need to access the member object.
 * Extra freestore allocations ("new" in constructor, "delete" in destructor).
 * Extra dynamic binding (reason given below).

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

Q94: What are relative costs of the 3 performance hits associated with
   allocating member objects from the freestore?

The three performance hits are enumerated in the previous FAQ:
 * By itself, an extra layer of indirection is small potatoes.
 * Freestore allocations can be a performance issue (the performance of the
   typical implementation of malloc degrades when there are many allocations;
   OO s/w can easily become "freestore bound" unless you're careful).
 * The extra dynamic binding comes from having a ptr rather than an object.
   Whenever the C++ compiler can know an object's EXACT class, virtual fn
   calls can be STATICALLY bound, which allows inlining.  Inlining allows
   zillions (would you believe half a dozen :-) optimization opportunities
   such as procedural integration, register lifetime issues, etc.  The C++
   compiler can know an object's exact class in three circumstances: local
   variables, global/static variables, and fully-contained member objects.

Thus fully-contained member objects allow significant optimizations that
wouldn't be possible under the "member objects-by-ptr" approach.  This is the
main reason that languages which enforce reference-semantics have "inherent"
performance challenges.

NOTE: PLEASE READ THE NEXT THREE FAQs TO GET A BALANCED PERSPECTIVE!

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

Q95: Are "inline virtual" member fns ever actually "inlined"?

Yes but...

A virtual call via a ptr or ref is always resolved dynamically, which can never
be inlined.  Reason: the compiler can't know which actual code to call until
run-time (i.e., dynamically), since the code may be from a derived class that
was created after the caller was compiled.

Therefore the only time an inline virtual call can be inlined is when the
compiler knows the "exact class" of the object which is the target of the
virtual function call.  This can happen only when the compiler has an actual
object rather than a pointer or reference to an object.  I.e., either with a
local object, a global/static object, or a fully contained object inside a
composite.

Note that the difference between inlining and non-inlining is normally MUCH
more significant than the difference between a regular fn call and a virtual fn
call.  For example, the difference between a regular fn call and a virtual fn
call is often just two extra memory references, but the difference between an
inline function and a non-inline function can be as much as an order of
magnitude (for zillions of calls to insignificant member fns, loss of inlining
virtual fns can result in 25X speed degradation!  [Doug Lea, "Customization in
C++," proc Usenix C++ 1990]).

A practical consequence of this insight: don't get bogged down in the endless
debates (or sales tactics!) of compiler/language vendors who compare the cost
of a virtual function call on their language/compiler with the same on another
language/compiler.  Such comparisons are largely meaningless when compared with
the ability of the language/compiler to "inline expand" member function calls.
I.e., many language implementation vendors make a big stink about how good
their dispatch strategy is, but if these implementations don't INLINE method
calls, the overall system performance would be poor, since it is inlining --NOT
dispatching-- that has the greatest performance impact.

NOTE: PLEASE READ THE NEXT TWO FAQs TO SEE THE OTHER SIDE OF THIS COIN!

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

Q96: Sounds like I should never use reference semantics, right?

Wrong.

Reference semantics are A Good Thing.  We can't live without pointers.  We just
don't want our s/w to be One Gigantic Rats Nest Of Pointers.  In C++, you can
pick and choose where you want reference semantics (ptrs/refs) and where you'd
like value semantics (where objects physically contain other objects etc).  In
a large system, there should be a balance.  However if you implement absolutely
EVERYTHING as a pointer, you'll get enormous speed hits.

Objects near the problem skin are larger than higher level objects.  The
IDENTITY of these "problem space" abstractions is usually more important than
their "value."  Thus reference semantics should be used for problem-space
objects.

Note that these problem space objects are normally at a higher level of
abstraction than the solution space objects, so the problem space objects
normally have a relatively lower frequency of interaction.  Therefore C++ gives
us an IDEAL situation: we choose reference semantics for objects that need
unique identity or that are too large to copy, and we can choose value
semantics for the others.  Thus the highest frequency objects will end up with
value semantics, since we install flexibility where it doesn't hurt us (only),
and we install performance where we need it most!

These are some of the many issues the come into play with real OO design.
OO/C++ mastery takes time and high quality training.  If you want a powerful
tool, you've got to invest.

           <<<<DON'T STOP NOW!  READ THE NEXT FAQ TOO!!>>>>

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

Q97: Does the poor performance of ref semantics mean I should pass-by-value?

Nope.

The previous FAQ were talking about MEMBER OBJECTS, not parameters.  Generally,
objects that are part of an inheritance hierarchy should be passed by ref or by
ptr, NOT by value, since only then do you get the (desired) dynamic binding
(pass-by-value doesn't mix with inheritance, since larger subclass objects get
"sliced" when passed by value as a base class object).

Unless compelling reasons are given to the contrary, member objects should be
by value and parameters should be by reference.  The discussion in the previous
few FAQs indicates some of the "compelling reasons" for when member objects
should be by reference.

--
Marshall Cline
--
Marshall P. Cline, Ph.D. / Paradigm Shift Inc / PO Box 5108 / Potsdam NY 13676
cline@sun.soe.clarkson.edu / 315-353-6100 / FAX: 315-353-6110

From ankh.iia.org!uunet!library.erc.clarkson.edu!sun.soe.clarkson.edu!cline Sun Dec 18 23:53:22 1994
Path: ankh.iia.org!uunet!library.erc.clarkson.edu!sun.soe.clarkson.edu!cline
From: cline@sun.soe.clarkson.edu (Marshall Cline)
Newsgroups: comp.lang.c++
Subject: C++ FAQ: posting #4/4
Followup-To: comp.lang.c++
Date: 14 Nov 1994 00:26:49 GMT
Organization: Paradigm Shift, Inc (training/consulting/OOD/OOP/C++)
Lines: 729
Sender: cline@sun.soe.clarkson.edu
Distribution: world
Expires: +1 month
Message-ID: <3a6as9$gd9@library.erc.clarkson.edu>
Reply-To: cline@parashift.com (Marshall Cline)
NNTP-Posting-Host: sun.soe.clarkson.edu
Summary: Please read this before posting to comp.lang.c++

comp.lang.c++ Frequently Asked Questions list (with answers, fortunately).
Copyright (C) 1991-94 Marshall P. Cline, Ph.D.
Posting 4 of 4.
Posting #1 explains copying permissions, (no)warranty, table-of-contents, etc

==============================================================================
SECTION 17: Linkage-to/relationship-with C
==============================================================================

Q98: How can I call a C function "f(int,char,float)" from C++ code?

Tell the C++ compiler that it is a C function:
	extern "C" void f(int,char,float);

Be sure to include the full function prototype.  A block of many C functions
can be grouped via braces, as in:

	extern "C" {
	  void* malloc(size_t);
	  char* strcpy(char* dest, const char* src);
	  int   printf(const char* fmt, ...);
	}

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

Q99: How can I create a C++ function "f(int,char,float)" that is callable by
   my C code?

The C++ compiler must know that "f(int,char,float)" is to be called by a C
compiler using the same "extern C" construct detailed in the previous FAQ.
Then you define the function in your C++ module:

	void f(int x, char y, float z)
	{
	  //...
	}

The "extern C" line tells the compiler that the external information sent to
the linker should use C calling conventions and name mangling (e.g., preceded
by a single underscore).  Since name overloading isn't supported by C, you
can't make several overloaded fns simultaneously callable by a C program.

Caveats and implementation dependencies:
 * your "main()" should be compiled with your C++ compiler (for static init).
 * your C++ compiler should direct the linking process (for special libraries).
 * your C and C++ compilers may need to from same vendor (calling convention).

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

Q100: Why's the linker giving errors for C/C++ fns being called from C++/C
   fns?

See the previous two FAQs on how to use "extern "C"."

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

Q101: How can I pass an object of a C++ class to/from a C function?

Here's an example:

	/****** C/C++ header file: Fred.h ******/
	#ifdef __cplusplus    /*"__cplusplus" is #defined if/only-if compiler is C++*/
	  extern "C" {
	#endif

	#ifdef __STDC__
	  extern void c_fn(struct Fred*);	/* ANSI-C prototypes */
	  extern struct Fred* cplusplus_callback_fn(struct Fred*);
	#else
	  extern void c_fn();			/* K&R style */
	  extern struct Fred* cplusplus_callback_fn();
	#endif

	#ifdef __cplusplus
	  }
	#endif

	#ifdef __cplusplus
	  class Fred {
	  public:
	    Fred();
	    void wilma(int);
	  private:
	    int a_;
	  };
	#endif

"Fred.C" would be a C++ module:

	#include "Fred.h"
	Fred::Fred() : a_(0) { }
	void Fred::wilma(int a) : a_(a) { }

	Fred* cplusplus_callback_fn(Fred* fred)
	{
	  fred->wilma(123);
	  return fred;
	}

"main.C" would be a C++ module:

	#include "Fred.h"

	int main()
	{
	  Fred fred;
	  c_fn(&fred);
	  return 0;
	}

"c-fn.c" would be a C module:

	#include "Fred.h"
	void c_fn(struct Fred* fred)
	{
	  cplusplus_callback_fn(fred);
	}

Passing ptrs to C++ objects to/from C fns will FAIL if you pass and get back
something that isn't EXACTLY the same pointer.  For example, DON'T pass a base
class ptr and receive back a derived class ptr, since your C compiler won't
understand the pointer conversions necessary to handle multiple and/or virtual
inheritance.

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

Q102: Can my C function access data in an object of a C++ class?

Sometimes.

(First read the previous FAQ on passing C++ objects to/from C functions.)

You can safely access a C++ object's data from a C function if the C++ class:
 * has no virtual functions (including inherited virtual fns)
 * has all its data in the same access-level section (private/protected/public)
 * has no fully-contained subobjects with virtual fns

If the C++ class has any base classes at all (or if any fully contained
subobjects have base classes), accessing the data will TECHNICALLY be
non-portable, since class layout under inheritance isn't imposed by the
language.  However in practice, all C++ compilers do it the same way: the base
class object appears first (in left-to-right order in the event of multiple
inheritance), and subobjects follow.

Furthermore, if the class (or any base class) contains any virtual functions,
you can often (but less than always) assume a "void*" appears in the object
either at the location of the first virtual function or as the first word in
the object.  Again, this is not required by the language, but it is the way
"everyone" does it.

If the class has any virtual base classes, it is even more complicated and less
portable.  One common implementation technique is for objects to contain an
object of the virtual base class (V) last (regardless of where "V" shows up as
a virtual base class in the inheritance hierarchy).  The rest of the object's
parts appear in the normal order.  Every derived class that has V as a virtual
base class actually has a POINTER to the V part of the final object.

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

Q103: Why do I feel like I'm "further from the machine" in C++ as opposed to
   C?

Because you are.

As an OOPL, C++ allows you to model the problem domain itself, which allows you
to program in the language of the problem domain rather than in the language of
the solution domain.

One of C's great strengths is the fact that it has "no hidden mechanism": what
you see is what you get.  You can read a C program and "see" every clock cycle.
This is not the case in C++; old line C programmers (such as many of us once
were) are often ambivalent (can anyone say, "hostile") about this feature, but
they soon realize that it provides a level of abstraction and economy of
expression which lowers maintenance costs without destroying run-time
performance.

Naturally you can write bad code in any language; C++ doesn't guarantee any
particular level of quality, reusability, abstraction, or any other measure of
"goodness."  C++ doesn't try to make it impossible for bad programmers to write
bad programs; it enables reasonable developers to create superior software.

==============================================================================
SECTION 18: Pointers to member functions
==============================================================================

Q104: Is the type of "ptr-to-member-fn" different from "ptr-to-fn"?

Yep.

Consider the following function:

	int f(char a, float b);

If this is an ordinary function, its type is:    int (*)      (char,float);
If this is a method of class Fred, its type is:  int (Fred::*)(char,float);

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

Q105: How can I ensure objects of my class are always created via "new" rather
   than as locals or global/static objects?

Make sure the class's constructors are "private:", and define "friend" or
"static" fns that return a ptr to the objects created via "new" (make the
constructors "protected:" if you want to allow derived classes).

	class Fred {	//only want to allow dynamicly allocated Fred's
	public:
	  static Fred* create()                 { return new Fred();     }
	  static Fred* create(int i)            { return new Fred(i);    }
	  static Fred* create(const Fred& fred) { return new Fred(fred); }
	private:
	  Fred();
	  Fred(int i);
	  Fred(const Fred& fred);
	  virtual ~Fred();
	};

	main()
	{
	  Fred* p = Fred::create(5);
	  ...
	  delete p;
	}

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

Q106: How do I pass a ptr to member fn to a signal handler, X event callback,
   etc?

Don't.

Because a member function is meaningless without an object to invoke it on, you
can't do this directly (if The X Windows System was rewritten in C++, it would
probably pass references to OBJECTS around, not just pointers to fns; naturally
the objects would embody the required function and probably a whole lot more).

As a patch for existing software, use a top-level (non-member) function as a
wrapper which takes an object obtained through some other technique (held in a
global, perhaps).  The top-level function would apply the desired member
function against the global object.

E.g., suppose you want to call Fred::memfn() on interrupt:

	class Fred {
	public:
	  void memfn();
	  static void staticmemfn();	//a static member fn can handle it
	  //...
	};

	//wrapper fn remembers the object on which to invoke memfn in a global:
	Fred* object_which_will_handle_signal;
	void Fred_memfn_wrapper() { object_which_will_handle_signal->memfn(); }

	main()
	{
	  /* signal(SIGINT, Fred::memfn); */   //Can NOT do this
	  signal(SIGINT, Fred_memfn_wrapper);  //Ok
	  signal(SIGINT, Fred::staticmemfn);   //Also Ok
	}

Note: static member functions do not require an actual object to be invoked, so
ptrs-to-static-member-fns are type compatible with regular ptrs-to-fns (see ARM
p.25, 158).

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

Q107: Why am I having trouble taking the address of a C++ function?

This is a corollary to the previous FAQ.

Long answer: In C++, member fns have an implicit parameter which points to the
object (the "this" ptr inside the member fn).  Normal C fns can be thought of
as having a different calling convention from member fns, so the types of their
ptrs (ptr-to-member-fn vs ptr-to-fn) are different and incompatible.  C++
introduces a new type of ptr, called a ptr-to-member, which can only be invoked
by providing an object (see ARM 5.5).

NOTE: do NOT attempt to "cast" a ptr-to-mem-fn into a ptr-to-fn; the result is
undefined and probably disastrous.  E.g., a ptr-to- member-fn is NOT required
to contain the machine addr of the appropriate fn (see ARM, 8.1.2c, p.158).  As
was said in the last example, if you have a ptr to a regular C fn, use either a
top-level (non-member) fn, or a "static" (class) member fn.

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

Q108: How do I declare an array of pointers to member functions?

Keep your sanity with "typedef".

	class Fred {
	public:
	  int f(char x, float y);
	  int g(char x, float y);
	  int h(char x, float y);
	  int i(char x, float y);
	  //...
	};

	typedef  int (Fred::*FredPtr)(char x, float y);

Here's the array of pointers to member functions:

	FredPtr a[4] = { &Fred::f, &Fred::g, &Fred::h, &Fred::i };

To call one of the member functions on object "fred":

	void userCode(Fred& fred, int methodNum, char x, float y)
	{
	  //assume "methodNum" is between 0 and 3 inclusive
	  (fred.*a[methodNum])(x, y);
	}

You can make the call somewhat clearer using a #define:

	#define  callMethod(object,ptrToMethod)   ((object).*(ptrToMethod))
	callMethod(fred, a[methodNum]) (x, y);

==============================================================================
SECTION 19: Container classes and templates
==============================================================================

Q109: How can I insert/access/change elements from a linked
   list/hashtable/etc?

I'll use an "inserting into a linked list" as a prototypical example.  It's easy
to allow insertion at the head and tail of the list, but limiting ourselves to
these would produce a library that is too weak (a weak library is almost worse
than no library).

This answer will be a lot to swallow for novice C++'ers, so I'll give a couple
of options.  The first option is easiest; the second and third are better.

[1] Empower the "List" with a "current location," and methods such as
advance(), backup(), atEnd(), atBegin(), getCurrElem(), setCurrElem(Elem),
insertElem(Elem), and removeElem().  Although this works in small examples, the
notion of "a" current position makes it difficult to access elements at two or
more positions within the List (e.g., "for all pairs x,y do the following...").

[2] Remove the above methods from the List itself, and move them to a separate
class, "ListPosition."  ListPosition would act as a "current position" within a
List.  This allows multiple positions within the same List.  ListPosition would
be a friend of List, so List can hide its innards from the outside world (else
the innards of List would have to be publicized via public methods in List).
Note: ListPosition can use operator overloading for things like advance() and
backup(), since operator overloading is syntactic sugar for normal methods.

[3] Consider the entire iteration as an atomic event, and create a class
template to embodies this event.  This enhances performance by allowing the
public access methods (which may be virtual fns) to be avoided during the inner
loop.  Unfortunately you get extra object code in the application, since
templates gain speed by duplicating code.  For more, see [Koenig, "Templates as
interfaces," JOOP, 4, 5 (Sept 91)], and [Stroustrup, "The C++ Programming
Language Second Edition," under "Comparator"].

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

Q110: What's the idea behind "templates"?

A template is a cookie-cutter that specifies how to cut cookies that all look
pretty much the same (although the cookies can be made of various kinds of
dough, they'll all have the same basic shape).  In the same way, a class
template is a cookie cutter to description of how to build a family of classes
that all look basically the same, and a function template describes how to
build a family of similar looking functions.

Class templates are often used to build type safe containers (although this
only scratches the surface for how they can be used).

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

Q111: What's the syntax / semantics for a "function template"?

Consider this function that swaps its two integer arguments:

	void swap(int& x, int& y)
	{
	  int tmp = x;
	  x = y;
	  y = tmp;
	}

If we also had to swap floats, longs, Strings, Sets, and FileSystems, we'd get
pretty tired of coding lines that look almost identical except for the type.
Mindless repetition is an ideal job for a computer, hence a function template:

	template<class T>
	void swap(T& x, T& y)
	{
	  T tmp = x;
	  x = y;
	  y = tmp;
	}

Every time we used "swap()" with a given pair of types, the compiler will go to
the above definition and will create yet another "template function" as an
instantiation of the above.  E.g.,

	main()
	{
	  int    i,j;  /*...*/  swap(i,j);  //instantiates a swap for "int"
	  float  a,b;  /*...*/  swap(a,b);  //instantiates a swap for "float"
	  char   c,d;  /*...*/  swap(c,d);  //instantiates a swap for "char"
	  String s,t;  /*...*/  swap(s,t);  //instantiates a swap for "String"
	}

(note: a "template function" is the instantiation of a "function template").

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

Q112: What's the syntax / semantics for a "class template"?

Consider a container class of that acts like an array of integers:

	//this would go into a header file such as "Array.h"
	class Array {
	public:
	  Array(int len=10)                  : len_(len), data_(new int[len]){}
	 ~Array()                            { delete [] data_; }
	  int len() const                    { return len_;     }
	  const int& operator[](int i) const { data_[check(i)]; }
	        int& operator[](int i)       { data_[check(i)]; }
	  Array(const Array&);
	  Array& operator= (const Array&);
	private:
	  int  len_;
	  int* data_;
	  int  check(int i) const
	    { if (i < 0 || i >= len_) throw BoundsViol("Array", i, len_);
	      return i; }
	};

Just as with "swap()" above, repeating the above over and over for Array of
float, of char, of String, of Array-of-String, etc, will become tedious.

	//this would go into a header file such as "Array.h"
	template<class T>
	class Array {
	public:
	  Array(int len=10)                : len_(len), data_(new T[len]) { }
	 ~Array()                          { delete [] data_; }
	  int len() const                  { return len_;     }
	  const T& operator[](int i) const { data_[check(i)]; }
	        T& operator[](int i)       { data_[check(i)]; }
	  Array(const Array<T>&);
	  Array& operator= (const Array<T>&);
	private:
	  int len_;
	  T*  data_;
	  int check(int i) const
	    { if (i < 0 || i >= len_) throw BoundsViol("Array", i, len_);
	      return i; }
	};

Unlike template functions, template classes (instantiations of class templates)
need to be explicit about the parameters over which they are instantiating:

	main()
	{
	  Array<int>           ai;
	  Array<float>         af;
	  Array<char*>         ac;
	  Array<String>        as;
	  Array< Array<int> >  aai;
	}              // ^^^-- note the space; do NOT use "Array<Array<int>>"
	               //       (the compiler sees ">>" as a single token).

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

Q113: What is a "parameterized type"?

Another way to say, "class templates."

A parameterized type is a type that is parameterized over another type or some
value.  List<int> is a type ("List") parameterized over another type ("int").

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

Q114: What is "genericity"?

Yet another way to say, "class templates."

Not to be confused with "generality" (which just means avoiding solutions which
are overly specific), "genericity" means class templates.

==============================================================================
SECTION 20: Nuances of particular implementations
==============================================================================

Q115: GNU C++ (g++) produces big executables for tiny programs; Why?

libg++ (the library used by g++) was probably compiled with debug info (-g).
On some machines, recompiling libg++ without debugging can save lots of disk
space (~1 Meg; the down-side: you'll be unable to trace into libg++ calls).
Merely "strip"ping the executable doesn't reclaim as much as recompiling
without -g followed by subsequent "strip"ping the resultant "a.out"s.

Use "size a.out" to see how big the program code and data segments really are,
rather than "ls -s a.out" which includes the symbol table.

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

Q116: Is there a yacc-able C++ grammar?

Jim Roskind is the author of a yacc grammar for C++. It's roughly compatible
with the portion of the language implemented by USL cfront 2.0 (no templates,
no exceptions, no run-time-type-identification).  Jim's grammar deviates from
C++ in a couple of minor-but-subtle ways.

The grammar can be accessed by anonymous ftp from the following sites:
 * ics.uci.edu (128.195.1.1) in "gnu/c++grammar2.0.tar.Z".
 * mach1.npac.syr.edu (128.230.7.14) in "pub/C++/c++grammar2.0.tar.Z".

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

Q117: What is C++ 1.2?  2.0?  2.1?  3.0?

These are not versions of the language, but rather versions of cfront, which
was the original C++ translator implemented by AT&T.  It has become generally
accepted to use these version numbers as if they were versions of the language
itself.

*VERY* roughly speaking, these are the major features:
 * 2.0 includes multiple/virtual inheritance and pure virtual functions.
 * 2.1 includes semi-nested classes and "delete [] ptr_to_array."
 * 3.0 includes fully-nested classes, templates and "i++" vs "++i."
 * 4.0 will include exceptions.

==============================================================================
SECTION 21: Miscellaneous technical and environmental issues
==============================================================================
SUBSECTION 21A: Miscellaneous technical issues:
==============================================================================

Q118: Why are classes with static data members getting linker errors?

Static data members must be explicitly defined in exactly one module.  E.g.,

	class Fred {
	public:
	  //...
	private:
	  static int i_;  //declares static data member "Fred::i_"
	  //...
	};

The linker will holler at you ("Fred::i_ is not defined") unless you define (as
opposed to declare) "Fred::i_" in (exactly) one of your source files:

	int Fred::i_ = some_expression_evaluating_to_an_int;
or:
	int Fred::i_;

The usual place to define static data members of class "Fred" is file "Fred.C"
(or "Fred.cpp", etc; whatever filename extension you use).

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

Q119: What's the difference between the keywords struct and class?

The members and base classes of a struct are public by default, while in class,
they default to private.  Note: you should make your base classes EXPLICITLY
public, private, or protected, rather than relying on the defaults.

"struct" and "class" are otherwise functionally equivalent.

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

Q120: Why can't I overload a function by its return type?

If you declare both "char f()" and "float f()", the compiler gives you an error
message, since calling simply "f()" would be ambiguous.

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

Q121: What is "persistence"?  What is a "persistent object"?

A persistent object can live after the program which created it has stopped.
Persistent objects can even outlive different versions of the creating program,
can outlive the disk system, the operating system, or even the hardware on
which the OS was running when they were created.

The challenge with persistent objects is to effectively store their method code
out on secondary storage along with their data bits (and the data bits and
method code of all member objects, and of all their member objects and base
classes, etc).  This is non-trivial when you have to do it yourself.  In C++,
you have to do it yourself.  C++/OO databases can help hide the mechanism for
all this.

==============================================================================
SUBSECTION 21B: Miscellaneous environmental issues:
==============================================================================

Q122: Is there a TeX or LaTeX macro that fixes the spacing on "C++"?

Yes, here are two:

\def\CC{C\raise.22ex\hbox{{\footnotesize +}}\raise.22ex\hbox{\footnotesize +}}

\def\CC{{C\hspace{-.05em}\raisebox{.4ex}{\tiny\bf ++}}}

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

Q123: Where can I access C++2LaTeX, a LaTeX pretty printer for C++ source?

Here are a few ftp locations:

Host aix370.rrz.uni-koeln.de   (134.95.80.1) Last updated 15:41 26 Apr 1991
    Location: /tex
      FILE      rw-rw-r--     59855  May  5  1990   C++2LaTeX-1.1.tar.Z
Host utsun.s.u-tokyo.ac.jp   (133.11.11.11) Last updated 05:06 20 Apr 1991
    Location: /TeX/macros
      FILE      rw-r--r--     59855  Mar  4 08:16   C++2LaTeX-1.1.tar.Z
Host nuri.inria.fr   (128.93.1.26) Last updated 05:23  9 Apr 1991
    Location: /TeX/tools
      FILE      rw-rw-r--     59855  Oct 23 16:05   C++2LaTeX-1.1.tar.Z
Host iamsun.unibe.ch   (130.92.64.10) Last updated 05:06  4 Apr 1991
    Location: /TeX
      FILE      rw-r--r--     59855  Apr 25  1990   C++2LaTeX-1.1.tar.Z
Host iamsun.unibe.ch   (130.92.64.10) Last updated 05:06  4 Apr 1991
    Location: /TeX
      FILE      rw-r--r--     51737  Apr 30  1990
      C++2LaTeX-1.1-PL1.tar.Z
Host tupac-amaru.informatik.rwth-aachen.de   (192.35.229.9) Last updated 05:07 18 Apr 1991
    Location: /pub/textproc/TeX
      FILE      rw-r--r--     72957  Oct 25 13:51  C++2LaTeX-1.1-PL4.tar.Z
Host wuarchive.wustl.edu   (128.252.135.4) Last updated 23:25 30 Apr 1991
    Location: /packages/tex/tex/192.35.229.9/textproc/TeX
      FILE      rw-rw-r--     49104  Apr 10  1990   C++2LaTeX-PL2.tar.Z
      FILE      rw-rw-r--     25835  Apr 10  1990   C++2LaTeX.tar.Z
Host tupac-amaru.informatik.rwth-aachen.de   (192.35.229.9) Last updated 05:07 18 Apr 1991
    Location: /pub/textproc/TeX
      FILE rw-r--r-- 74015  Mar 22 16:23 C++2LaTeX-1.1-PL5.tar.Z
    Location: /pub
      FILE rw-r--r-- 74015  Mar 22 16:23 C++2LaTeX-1.1-PL5.tar.Z
Host sol.cs.ruu.nl   (131.211.80.5) Last updated 05:10 15 Apr 1991
    Location: /TEX/TOOLS
      FILE      rw-r--r--     74015  Apr  4 21:02x   C++2LaTeX-1.1-PL5.tar.Z
Host tupac-amaru.informatik.rwth-aachen.de (192.35.229.9) Last updated 05:07 18 Apr 1991
    Location: /pub/textproc/TeX
      FILE      rw-r--r--      4792  Sep 11  1990 C++2LaTeX-1.1-patch#1
      FILE      rw-r--r--      2385  Sep 11  1990 C++2LaTeX-1.1-patch#2
      FILE      rw-r--r--      5069  Sep 11  1990 C++2LaTeX-1.1-patch#3
      FILE      rw-r--r--      1587  Oct 25 13:58 C++2LaTeX-1.1-patch#4
      FILE      rw-r--r--      8869  Mar 22 16:23 C++2LaTeX-1.1-patch#5
      FILE      rw-r--r--      1869  Mar 22 16:23 C++2LaTeX.README
Host rusmv1.rus.uni-stuttgart.de   (129.69.1.12) Last updated 05:13 13 Apr 1991
    Location: /soft/tex/utilities
      FILE      rw-rw-r--    163840  Jul 16  1990   C++2LaTeX-1.1.tar

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

Q124: Where can I access "tgrind," a pretty printer for C++/C/etc source?

"tgrind" reads a C++ source file, and spits out something that looks pretty on
most Unix printers.  It usually comes with the public distribution of TeX and
LaTeX; look in the directory: "...tex82/contrib/van/tgrind".  A more up-to-date
version of tgrind by Jerry Leichter can be found on: venus.ycc.yale.edu in
[.TGRIND].

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

Q125: Is there a C++-mode for GNU emacs?  If so, where can I get it?

Yes, there is a C++-mode for GNU emacs.  You can get it via:

c++-mode-2 (1.0)  87-12-08
     Bruce Eckel,Thomas Keffer, <eckel@beluga.ocean.washington.edu,uw-beaver!beluga!eckel,keffer@sperm.ocean.washington.edu>
     archive.cis.ohio-state.edu:/pub/gnu/emacs/elisp-archive/as-is/c++-mode-2.el.Z

     Another C++ major mode.
c++-mode	  89-11-07
     Dave Detlefs, et al, <dld@cs.cmu.edu>
     archive.cis.ohio-state.edu:/pub/gnu/emacs/elisp-archive/modes/c++-mode.el.Z

     C++ major mode.
c++		  90-02-01
     David Detlefs, Stewart Clamen, <dld@f.gp.cs.cmu.edu,clamen@cs.cmu.edu>
     archive.cis.ohio-state.edu:/pub/gnu/emacs/elisp-archive/modes/c++.el.Z
     C++ code editing commands for Emacs

c-support (46)	  89-11-04
     Lynn Slater, <lrs@indetech.com>
     archive.cis.ohio-state.edu:/pub/gnu/emacs/elisp-archive/misc/c-support.el.Z
     Partial support for team C/C++ development.

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

Q126: Where can I get OS-specific FAQs answered (e.g.,BC++,DOS,Windows,etc)?

see comp.os.msdos.programmer, BC++ and Zortech mailing lists, BC++ and
   Zortech bug lists, comp.windows.ms.programmer, comp.unix.programmer, etc.

You can subscribe to the BC++ mailing list by sending email to:
|	To: listserv@ucf1vm.cc.ucf.edu   <---or LISTSERV@UCF1VM.BITNET
|	Subject: SUB TCPLUS-L
|	Reply-to: you@your.email.addr    <---i.e., put your return address here

The BC++ bug report is available via anonymous ftp from sun.soe.clarkson.edu
[128.153.12.3] from the file ~ftp/pub/Turbo-C++/bug-report
(also, I post it on comp.lang.c++ on the first each month).

Relevant email addresses:
	ztc-list@zortech.com          General requests and discussion
	ztc-list-request@zortech.com  Requests to be added to ztc-list
	ztc-bugs@zortech.com          For _short_ bug reports

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

Q127: Why does my DOS C++ program says "Sorry: floating point code not
   linked"?

The compiler attempts to save space in the executable by not including the
float-to-string format conversion routines unless they are necessary, but
sometimes it guesses wrong, and gives you the above error message.  You can fix
this by (1) using <iostream.h> instead of <stdio.h>, or (2) by including the
following function somewhere in your compilation (but don't call it!):

	static void dummyfloat(float *x) { float y; dummyfloat(&y); }

See FAQ on stream I/O for more reasons to use <iostream.h> vs <stdio.h>.

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

--
Marshall Cline
--
Marshall P. Cline, Ph.D. / Paradigm Shift Inc / PO Box 5108 / Potsdam NY 13676
cline@sun.soe.clarkson.edu / 315-353-6100 / FAX: 315-353-6110

From ankh.iia.org!uunet!news.mathworks.com!news.kei.com!ub!library.erc.clarkson.edu!sun.soe.clarkson.edu!cline Sun Dec 18 23:53:23 1994
Path: ankh.iia.org!uunet!news.mathworks.com!news.kei.com!ub!library.erc.clarkson.edu!sun.soe.clarkson.edu!cline
From: cline@sun.soe.clarkson.edu (Marshall Cline)
Newsgroups: comp.lang.c++
Subject: C++ FAQ: posting #4/4
Followup-To: comp.lang.c++
Date: 13 Dec 1994 05:58:05 GMT
Organization: Paradigm Shift, Inc (training/consulting/OOD/OOP/C++)
Lines: 761
Sender: cline@sun.soe.clarkson.edu
Distribution: world
Expires: +1 month
Message-ID: <3cjd5d$lch@library.erc.clarkson.edu>
Reply-To: cline@parashift.com (Marshall Cline)
NNTP-Posting-Host: sun.soe.clarkson.edu
Summary: Please read this before posting to comp.lang.c++

comp.lang.c++ Frequently Asked Questions list (with answers, fortunately).
Copyright (C) 1991-94 Marshall P. Cline, Ph.D.
Posting 4 of 4.
Posting #1 explains copying permissions, (no)warranty, table-of-contents, etc

==============================================================================
SECTION 17: Linkage-to/relationship-with C
==============================================================================

Q98: How can I call a C function "f(int,char,float)" from C++ code?

Tell the C++ compiler that it is a C function:
	extern "C" void f(int,char,float);

Be sure to include the full function prototype.  A block of many C functions
can be grouped via braces, as in:

	extern "C" {
	  void* malloc(size_t);
	  char* strcpy(char* dest, const char* src);
	  int   printf(const char* fmt, ...);
	}

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

Q99: How can I create a C++ function "f(int,char,float)" that is callable by
   my C code?

The C++ compiler must know that "f(int,char,float)" is to be called by a C
compiler using the same "extern C" construct detailed in the previous FAQ.
Then you define the function in your C++ module:

	void f(int x, char y, float z)
	{
	  //...
	}

The "extern C" line tells the compiler that the external information sent to
the linker should use C calling conventions and name mangling (e.g., preceded
by a single underscore).  Since name overloading isn't supported by C, you
can't make several overloaded fns simultaneously callable by a C program.

Caveats and implementation dependencies:
 * your "main()" should be compiled with your C++ compiler (for static init).
 * your C++ compiler should direct the linking process (for special libraries).
 * your C and C++ compilers may need to come from same vendor and have
   compatible versions (i.e., needs same calling convention, etc.).

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

Q100: Why's the linker giving errors for C/C++ fns being called from C++/C
   fns?

See the previous two FAQs on how to use "extern "C"."

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

Q101: How can I pass an object of a C++ class to/from a C function?

Here's an example:

	/****** C/C++ header file: Fred.h ******/
	#ifdef __cplusplus    /*"__cplusplus" is #defined if/only-if compiler is C++*/
	  extern "C" {
	#endif

	#ifdef __STDC__
	  extern void c_fn(struct Fred*);	/* ANSI-C prototypes */
	  extern struct Fred* cplusplus_callback_fn(struct Fred*);
	#else
	  extern void c_fn();			/* K&R style */
	  extern struct Fred* cplusplus_callback_fn();
	#endif

	#ifdef __cplusplus
	  }
	#endif

	#ifdef __cplusplus
	  class Fred {
	  public:
	    Fred();
	    void wilma(int);
	  private:
	    int a_;
	  };
	#endif

"Fred.C" would be a C++ module:

	#include "Fred.h"
	Fred::Fred() : a_(0) { }
	void Fred::wilma(int a) : a_(a) { }

	Fred* cplusplus_callback_fn(Fred* fred)
	{
	  fred->wilma(123);
	  return fred;
	}

"main.C" would be a C++ module:

	#include "Fred.h"

	int main()
	{
	  Fred fred;
	  c_fn(&fred);
	  return 0;
	}

"c-fn.c" would be a C module:

	#include "Fred.h"
	void c_fn(struct Fred* fred)
	{
	  cplusplus_callback_fn(fred);
	}

Passing ptrs to C++ objects to/from C fns will FAIL if you pass and get back
something that isn't EXACTLY the same pointer.  For example, DON'T pass a base
class ptr and receive back a derived class ptr, since your C compiler won't
understand the pointer conversions necessary to handle multiple and/or virtual
inheritance.

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

Q102: Can my C function access data in an object of a C++ class?

Sometimes.

(First read the previous FAQ on passing C++ objects to/from C functions.)

You can safely access a C++ object's data from a C function if the C++ class:
 * has no virtual functions (including inherited virtual fns)
 * has all its data in the same access-level section (private/protected/public)
 * has no fully-contained subobjects with virtual fns

If the C++ class has any base classes at all (or if any fully contained
subobjects have base classes), accessing the data will TECHNICALLY be
non-portable, since class layout under inheritance isn't imposed by the
language.  However in practice, all C++ compilers do it the same way: the base
class object appears first (in left-to-right order in the event of multiple
inheritance), and subobjects follow.

Furthermore, if the class (or any base class) contains any virtual functions,
you can often (but less than always) assume a "void*" appears in the object
either at the location of the first virtual function or as the first word in
the object.  Again, this is not required by the language, but it is the way
"everyone" does it.

If the class has any virtual base classes, it is even more complicated and less
portable.  One common implementation technique is for objects to contain an
object of the virtual base class (V) last (regardless of where "V" shows up as
a virtual base class in the inheritance hierarchy).  The rest of the object's
parts appear in the normal order.  Every derived class that has V as a virtual
base class actually has a POINTER to the V part of the final object.

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

Q103: Why do I feel like I'm "further from the machine" in C++ as opposed to
   C?

Because you are.

As an OOPL, C++ allows you to model the problem domain itself, which allows you
to program in the language of the problem domain rather than in the language of
the solution domain.

One of C's great strengths is the fact that it has "no hidden mechanism": what
you see is what you get.  You can read a C program and "see" every clock cycle.
This is not the case in C++; old line C programmers (such as many of us once
were) are often ambivalent (can anyone say, "hostile") about this feature, but
they soon realize that it provides a level of abstraction and economy of
expression which lowers maintenance costs without destroying run-time
performance.

Naturally you can write bad code in any language; C++ doesn't guarantee any
particular level of quality, reusability, abstraction, or any other measure of
"goodness."  C++ doesn't try to make it impossible for bad programmers to write
bad programs; it enables reasonable developers to create superior software.

==============================================================================
SECTION 18: Pointers to member functions
==============================================================================

Q104: Is the type of "ptr-to-member-fn" different from "ptr-to-fn"?

Yep.

Consider the following function:

	int f(char a, float b);

If this is an ordinary function, its type is:    int (*)      (char,float);
If this is a method of class Fred, its type is:  int (Fred::*)(char,float);

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

Q105: How can I ensure objects of my class are always created via "new" rather
   than as locals or global/static objects?

Make sure the class's constructors are "private:", and define "friend" or
"static" fns that return a ptr to the objects created via "new" (make the
constructors "protected:" if you want to allow derived classes).

	class Fred {	//only want to allow dynamicly allocated Fred's
	public:
	  static Fred* create()                 { return new Fred();     }
	  static Fred* create(int i)            { return new Fred(i);    }
	  static Fred* create(const Fred& fred) { return new Fred(fred); }
	private:
	  Fred();
	  Fred(int i);
	  Fred(const Fred& fred);
	  virtual ~Fred();
	};

	main()
	{
	  Fred* p = Fred::create(5);
	  ...
	  delete p;
	}

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

Q106: How do I pass a ptr to member fn to a signal handler, X event callback,
   etc?

Don't.

Because a member function is meaningless without an object to invoke it on, you
can't do this directly (if The X Windows System was rewritten in C++, it would
probably pass references to OBJECTS around, not just pointers to fns; naturally
the objects would embody the required function and probably a whole lot more).

As a patch for existing software, use a top-level (non-member) function as a
wrapper which takes an object obtained through some other technique (held in a
global, perhaps).  The top-level function would apply the desired member
function against the global object.

E.g., suppose you want to call Fred::memfn() on interrupt:

	class Fred {
	public:
	  void memfn();
	  static void staticmemfn();	//a static member fn can handle it
	  //...
	};

	//wrapper fn remembers the object on which to invoke memfn in a global:
	Fred* object_which_will_handle_signal;
	void Fred_memfn_wrapper() { object_which_will_handle_signal->memfn(); }

	main()
	{
	  /* signal(SIGINT, Fred::memfn); */   //Can NOT do this
	  signal(SIGINT, Fred_memfn_wrapper);  //Ok
	  signal(SIGINT, Fred::staticmemfn);   //Also Ok
	}

Note: static member functions do not require an actual object to be invoked, so
ptrs-to-static-member-fns are type compatible with regular ptrs-to-fns (see ARM
p.25, 158).

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

Q107: Why am I having trouble taking the address of a C++ function?

This is a corollary to the previous FAQ.

Long answer: In C++, member fns have an implicit parameter which points to the
object (the "this" ptr inside the member fn).  Normal C fns can be thought of
as having a different calling convention from member fns, so the types of their
ptrs (ptr-to-member-fn vs ptr-to-fn) are different and incompatible.  C++
introduces a new type of ptr, called a ptr-to-member, which can be invoked only
by providing an object (see ARM 5.5).

NOTE: do NOT attempt to "cast" a ptr-to-mem-fn into a ptr-to-fn; the result is
undefined and probably disastrous.  E.g., a ptr-to- member-fn is NOT required
to contain the machine addr of the appropriate fn (see ARM, 8.1.2c, p.158).  As
was said in the last example, if you have a ptr to a regular C fn, use either a
top-level (non-member) fn, or a "static" (class) member fn.

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

Q108: How do I declare an array of pointers to member functions?

Keep your sanity with "typedef".

	class Fred {
	public:
	  int f(char x, float y);
	  int g(char x, float y);
	  int h(char x, float y);
	  int i(char x, float y);
	  //...
	};

	typedef  int (Fred::*FredPtr)(char x, float y);

Here's the array of pointers to member functions:

	FredPtr a[4] = { &Fred::f, &Fred::g, &Fred::h, &Fred::i };

To call one of the member functions on object "fred":

	void userCode(Fred& fred, int methodNum, char x, float y)
	{
	  //assume "methodNum" is between 0 and 3 inclusive
	  (fred.*a[methodNum])(x, y);
	}

You can make the call somewhat clearer using a #define:

	#define  callMethod(object,ptrToMethod)   ((object).*(ptrToMethod))
	callMethod(fred, a[methodNum]) (x, y);

==============================================================================
SECTION 19: Container classes and templates
==============================================================================

Q109: How can I insert/access/change elements from a linked
   list/hashtable/etc?

I'll use an "inserting into a linked list" as a prototypical example.  It's easy
to allow insertion at the head and tail of the list, but limiting ourselves to
these would produce a library that is too weak (a weak library is almost worse
than no library).

This answer will be a lot to swallow for novice C++'ers, so I'll give a couple
of options.  The first option is easiest; the second and third are better.

[1] Empower the "List" with a "current location," and methods such as
advance(), backup(), atEnd(), atBegin(), getCurrElem(), setCurrElem(Elem),
insertElem(Elem), and removeElem().  Although this works in small examples, the
notion of "a" current position makes it difficult to access elements at two or
more positions within the List (e.g., "for all pairs x,y do the following...").

[2] Remove the above methods from the List itself, and move them to a separate
class, "ListPosition."  ListPosition would act as a "current position" within a
List.  This allows multiple positions within the same List.  ListPosition would
be a friend of List, so List can hide its innards from the outside world (else
the innards of List would have to be publicized via public methods in List).
Note: ListPosition can use operator overloading for things like advance() and
backup(), since operator overloading is syntactic sugar for normal methods.

[3] Consider the entire iteration as an atomic event, and create a class
template to embodies this event.  This enhances performance by allowing the
public access methods (which may be virtual fns) to be avoided during the inner
loop.  Unfortunately you get extra object code in the application, since
templates gain speed by duplicating code.  For more, see [Koenig, "Templates as
interfaces," JOOP, 4, 5 (Sept 91)], and [Stroustrup, "The C++ Programming
Language Second Edition," under "Comparator"].

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

Q110: What's the idea behind "templates"?

A template is a cookie-cutter that specifies how to cut cookies that all look
pretty much the same (although the cookies can be made of various kinds of
dough, they'll all have the same basic shape).  In the same way, a class
template is a cookie cutter to description of how to build a family of classes
that all look basically the same, and a function template describes how to
build a family of similar looking functions.

Class templates are often used to build type safe containers (although this
only scratches the surface for how they can be used).

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

Q111: What's the syntax / semantics for a "function template"?

Consider this function that swaps its two integer arguments:

	void swap(int& x, int& y)
	{
	  int tmp = x;
	  x = y;
	  y = tmp;
	}

If we also had to swap floats, longs, Strings, Sets, and FileSystems, we'd get
pretty tired of coding lines that look almost identical except for the type.
Mindless repetition is an ideal job for a computer, hence a function template:

	template<class T>
	void swap(T& x, T& y)
	{
	  T tmp = x;
	  x = y;
	  y = tmp;
	}

Every time we used "swap()" with a given pair of types, the compiler will go to
the above definition and will create yet another "template function" as an
instantiation of the above.  E.g.,

	main()
	{
	  int    i,j;  /*...*/  swap(i,j);  //instantiates a swap for "int"
	  float  a,b;  /*...*/  swap(a,b);  //instantiates a swap for "float"
	  char   c,d;  /*...*/  swap(c,d);  //instantiates a swap for "char"
	  String s,t;  /*...*/  swap(s,t);  //instantiates a swap for "String"
	}

(note: a "template function" is the instantiation of a "function template").

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

Q112: What's the syntax / semantics for a "class template"?

Consider a container class of that acts like an array of integers:

	//this would go into a header file such as "Array.h"
	class Array {
	public:
	  Array(int len=10)                  : len_(len), data_(new int[len]){}
	 ~Array()                            { delete [] data_; }
	  int len() const                    { return len_;     }
	  const int& operator[](int i) const { data_[check(i)]; }
	        int& operator[](int i)       { data_[check(i)]; }
	  Array(const Array&);
	  Array& operator= (const Array&);
	private:
	  int  len_;
	  int* data_;
	  int  check(int i) const
	    { if (i < 0 || i >= len_) throw BoundsViol("Array", i, len_);
	      return i; }
	};

Just as with "swap()" above, repeating the above over and over for Array of
float, of char, of String, of Array-of-String, etc, will become tedious.

	//this would go into a header file such as "Array.h"
	template<class T>
	class Array {
	public:
	  Array(int len=10)                : len_(len), data_(new T[len]) { }
	 ~Array()                          { delete [] data_; }
	  int len() const                  { return len_;     }
	  const T& operator[](int i) const { data_[check(i)]; }
	        T& operator[](int i)       { data_[check(i)]; }
	  Array(const Array<T>&);
	  Array& operator= (const Array<T>&);
	private:
	  int len_;
	  T*  data_;
	  int check(int i) const
	    { if (i < 0 || i >= len_) throw BoundsViol("Array", i, len_);
	      return i; }
	};

Unlike template functions, template classes (instantiations of class templates)
need to be explicit about the parameters over which they are instantiating:

	main()
	{
	  Array<int>           ai;
	  Array<float>         af;
	  Array<char*>         ac;
	  Array<String>        as;
	  Array< Array<int> >  aai;
	}              // ^^^-- note the space; do NOT use "Array<Array<int>>"
	               //       (the compiler sees ">>" as a single token).

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

Q113: What is a "parameterized type"?

Another way to say, "class templates."

A parameterized type is a type that is parameterized over another type or some
value.  List<int> is a type ("List") parameterized over another type ("int").

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

Q114: What is "genericity"?

Yet another way to say, "class templates."

Not to be confused with "generality" (which just means avoiding solutions which
are overly specific), "genericity" means class templates.

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

Q115: Where can I get a copy of "STL"?

"STL" is the "Standard Templates Library".  You can get a copy from:

STL HP official site:	ftp://butler.hpl.hp.com/stl
STL code alternate:	ftp://ftp.cs.rpi.edu/stl
STL code + examples:	http://www.cs.rpi.edu/~musser/stl.html
hacks for GCC-2.6.3:	ftp://ftp.uni-bremen.de/pub/.mount/ruin/C++/STL

==============================================================================
SECTION 20: Nuances of particular implementations
==============================================================================

Q116: GNU C++ (g++) produces big executables for tiny programs; Why?

libg++ (the library used by g++) was probably compiled with debug info (-g).
On some machines, recompiling libg++ without debugging can save lots of disk
space (~1 Meg; the down-side: you'll be unable to trace into libg++ calls).
Merely "strip"ping the executable doesn't reclaim as much as recompiling
without -g followed by subsequent "strip"ping the resultant "a.out"s.

Use "size a.out" to see how big the program code and data segments really are,
rather than "ls -s a.out" which includes the symbol table.

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

Q117: Is there a yacc-able C++ grammar?

Jim Roskind is the author of a yacc grammar for C++. It's roughly compatible
with the portion of the language implemented by USL cfront 2.0 (no templates,
no exceptions, no run-time-type-identification).  Jim's grammar deviates from
C++ in a couple of minor-but-subtle ways.

The grammar can be accessed by anonymous ftp from the following sites:
 * ics.uci.edu (128.195.1.1) in "gnu/c++grammar2.0.tar.Z".
 * mach1.npac.syr.edu (128.230.7.14) in "pub/C++/c++grammar2.0.tar.Z".

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

Q118: What is C++ 1.2?  2.0?  2.1?  3.0?

These are not versions of the language, but rather versions of cfront, which
was the original C++ translator implemented by AT&T.  It has become generally
accepted to use these version numbers as if they were versions of the language
itself.

*VERY* roughly speaking, these are the major features:
 * 2.0 includes multiple/virtual inheritance and pure virtual functions.
 * 2.1 includes semi-nested classes and "delete [] ptr_to_array."
 * 3.0 includes fully-nested classes, templates and "i++" vs "++i."
 * 4.0 will include exceptions.

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

Q119: If name mangling was standardized, could I link code compiled with
   compilers from different compiler vendors?

Short answer: Probably not.

In other words, some people would like to see name mangling standards
incorporated into the proposed C++ ANSI standards in an attempt to avoiding
having to purchase different versions of class libraries for different
compiler vendors.  However name mangling differences are one of the smallest
differences between implementations, even on the same platform.  Here is a
partial list of other differences:

1) Number and type of hidden arguments to member functions.
   1a) is 'this' handled specially?
   1b) where is the return-by-value pointer passed?
2) Assuming a vtable is used:
   2a) what is its contents and layout?
   2b) where/how is the adjustment to 'this' made for multiple inheritance?
3) How are classes laid out, including:
   3a) location of base classes?
   3b) handling of virtual base classes?
   3c) location of vtable pointers, if vtables are used?
4) Calling convention for functions, including:
   4a) does caller or callee adjust the stack?
   4b) where are the actual parameters placed?
   4c) in what order are the actual parameters passed?
   4d) how are registers saved?
   4e) where does the return value go?
   4f) special rules for passing or returning structs or doubles?
   4g) special rules for saving registers when calling leaf functions?
5) How is the run-time-type-identification laid out?
6) How does the runtime exception handling system know which local objects
   need to be destructed during an exception throw?

==============================================================================
SECTION 21: Miscellaneous technical and environmental issues
==============================================================================
SUBSECTION 21A: Miscellaneous technical issues:
==============================================================================

Q120: Why are classes with static data members getting linker errors?

Static data members must be explicitly defined in exactly one module.  E.g.,

	class Fred {
	public:
	  //...
	private:
	  static int i_;  //declares static data member "Fred::i_"
	  //...
	};

The linker will holler at you ("Fred::i_ is not defined") unless you define (as
opposed to declare) "Fred::i_" in (exactly) one of your source files:

	int Fred::i_ = some_expression_evaluating_to_an_int;
or:
	int Fred::i_;

The usual place to define static data members of class "Fred" is file "Fred.C"
(or "Fred.cpp", etc; whatever filename extension you use).

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

Q121: What's the difference between the keywords struct and class?

The members and base classes of a struct are public by default, while in class,
they default to private.  Note: you should make your base classes EXPLICITLY
public, private, or protected, rather than relying on the defaults.

"struct" and "class" are otherwise functionally equivalent.

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

Q122: Why can't I overload a function by its return type?

If you declare both "char f()" and "float f()", the compiler gives you an error
message, since calling simply "f()" would be ambiguous.

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

Q123: What is "persistence"?  What is a "persistent object"?

A persistent object can live after the program which created it has stopped.
Persistent objects can even outlive different versions of the creating program,
can outlive the disk system, the operating system, or even the hardware on
which the OS was running when they were created.

The challenge with persistent objects is to effectively store their method code
out on secondary storage along with their data bits (and the data bits and
method code of all member objects, and of all their member objects and base
classes, etc).  This is non-trivial when you have to do it yourself.  In C++,
you have to do it yourself.  C++/OO databases can help hide the mechanism for
all this.

==============================================================================
SUBSECTION 21B: Miscellaneous environmental issues:
==============================================================================

Q124: Is there a TeX or LaTeX macro that fixes the spacing on "C++"?

Yes, here are two:

\def\CC{C\raise.22ex\hbox{{\footnotesize +}}\raise.22ex\hbox{\footnotesize +}}

\def\CC{{C\hspace{-.05em}\raisebox{.4ex}{\tiny\bf ++}}}

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

Q125: Where can I access C++2LaTeX, a LaTeX pretty printer for C++ source?

Here are a few ftp locations:

Host aix370.rrz.uni-koeln.de   (134.95.80.1) Last updated 15:41 26 Apr 1991
    Location: /tex
      FILE      rw-rw-r--     59855  May  5  1990   C++2LaTeX-1.1.tar.Z
Host utsun.s.u-tokyo.ac.jp   (133.11.11.11) Last updated 05:06 20 Apr 1991
    Location: /TeX/macros
      FILE      rw-r--r--     59855  Mar  4 08:16   C++2LaTeX-1.1.tar.Z
Host nuri.inria.fr   (128.93.1.26) Last updated 05:23  9 Apr 1991
    Location: /TeX/tools
      FILE      rw-rw-r--     59855  Oct 23 16:05   C++2LaTeX-1.1.tar.Z
Host iamsun.unibe.ch   (130.92.64.10) Last updated 05:06  4 Apr 1991
    Location: /TeX
      FILE      rw-r--r--     59855  Apr 25  1990   C++2LaTeX-1.1.tar.Z
Host iamsun.unibe.ch   (130.92.64.10) Last updated 05:06  4 Apr 1991
    Location: /TeX
      FILE      rw-r--r--     51737  Apr 30  1990
      C++2LaTeX-1.1-PL1.tar.Z
Host tupac-amaru.informatik.rwth-aachen.de   (192.35.229.9) Last updated 05:07 18 Apr 1991
    Location: /pub/textproc/TeX
      FILE      rw-r--r--     72957  Oct 25 13:51  C++2LaTeX-1.1-PL4.tar.Z
Host wuarchive.wustl.edu   (128.252.135.4) Last updated 23:25 30 Apr 1991
    Location: /packages/tex/tex/192.35.229.9/textproc/TeX
      FILE      rw-rw-r--     49104  Apr 10  1990   C++2LaTeX-PL2.tar.Z
      FILE      rw-rw-r--     25835  Apr 10  1990   C++2LaTeX.tar.Z
Host tupac-amaru.informatik.rwth-aachen.de   (192.35.229.9) Last updated 05:07 18 Apr 1991
    Location: /pub/textproc/TeX
      FILE rw-r--r-- 74015  Mar 22 16:23 C++2LaTeX-1.1-PL5.tar.Z
    Location: /pub
      FILE rw-r--r-- 74015  Mar 22 16:23 C++2LaTeX-1.1-PL5.tar.Z
Host sol.cs.ruu.nl   (131.211.80.5) Last updated 05:10 15 Apr 1991
    Location: /TEX/TOOLS
      FILE      rw-r--r--     74015  Apr  4 21:02x   C++2LaTeX-1.1-PL5.tar.Z
Host tupac-amaru.informatik.rwth-aachen.de (192.35.229.9) Last updated 05:07 18 Apr 1991
    Location: /pub/textproc/TeX
      FILE      rw-r--r--      4792  Sep 11  1990 C++2LaTeX-1.1-patch#1
      FILE      rw-r--r--      2385  Sep 11  1990 C++2LaTeX-1.1-patch#2
      FILE      rw-r--r--      5069  Sep 11  1990 C++2LaTeX-1.1-patch#3
      FILE      rw-r--r--      1587  Oct 25 13:58 C++2LaTeX-1.1-patch#4
      FILE      rw-r--r--      8869  Mar 22 16:23 C++2LaTeX-1.1-patch#5
      FILE      rw-r--r--      1869  Mar 22 16:23 C++2LaTeX.README
Host rusmv1.rus.uni-stuttgart.de   (129.69.1.12) Last updated 05:13 13 Apr 1991
    Location: /soft/tex/utilities
      FILE      rw-rw-r--    163840  Jul 16  1990   C++2LaTeX-1.1.tar

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

Q126: Where can I access "tgrind," a pretty printer for C++/C/etc source?

"tgrind" reads a C++ source file, and spits out something that looks pretty on
most Unix printers.  It usually comes with the public distribution of TeX and
LaTeX; look in the directory: "...tex82/contrib/van/tgrind".  A more up-to-date
version of tgrind by Jerry Leichter can be found on: venus.ycc.yale.edu in
[.TGRIND].

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

Q127: Is there a C++-mode for GNU emacs?  If so, where can I get it?

Yes, there is a C++-mode for GNU emacs.

The latest and greatest version of C++-mode (and c-mode) is implemented in the
file cc-mode.el.  It is an extension of Detlef & Clamen's version.  It now
comes with GNU emacs.

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

Q128: Where can I get OS-specific FAQs answered (e.g.,BC++,DOS,Windows,etc)?

see comp.os.msdos.programmer, BC++ and Zortech mailing lists, BC++ and
   Zortech bug lists, comp.windows.ms.programmer, comp.unix.programmer, etc.

You can subscribe to the BC++ mailing list by sending email to:
|	To: listserv@ucf1vm.cc.ucf.edu   <---or LISTSERV@UCF1VM.BITNET
|	Subject: SUB TCPLUS-L
|	Reply-to: you@your.email.addr    <---i.e., put your return address here

The BC++ bug report is available via anonymous ftp from sun.soe.clarkson.edu
[128.153.12.3] from the file ~ftp/pub/Turbo-C++/bug-report
(also, I post it on comp.lang.c++ on the first each month).

Relevant email addresses:
	ztc-list@zortech.com          General requests and discussion
	ztc-list-request@zortech.com  Requests to be added to ztc-list
	ztc-bugs@zortech.com          For _short_ bug reports

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

Q129: Why does my DOS C++ program says "Sorry: floating point code not
   linked"?

The compiler attempts to save space in the executable by not including the
float-to-string format conversion routines unless they are necessary, but
sometimes it guesses wrong, and gives you the above error message.  You can fix
this by (1) using <iostream.h> instead of <stdio.h>, or (2) by including the
following function somewhere in your compilation (but don't call it!):

	static void dummyfloat(float *x) { float y; dummyfloat(&y); }

See FAQ on stream I/O for more reasons to use <iostream.h> vs <stdio.h>.

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

--
Marshall Cline
--
Marshall P. Cline, Ph.D. / Paradigm Shift Inc / PO Box 5108 / Potsdam NY 13676
cline@sun.soe.clarkson.edu / 315-353-6100 / FAX: 315-353-6110

