Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!nycmny1-snh1.gtei.net!cpk-news-hub1.bbnplanet.com!news.gtei.net!news.tele.dk!small.news.tele.dk!207.115.63.138!newscon04.news.prodigy.com!newsmst01.news.prodigy.com!prodigy.com!postmaster.news.prodigy.com!newssvr12.news.prodigy.com.POSTED!not-for-mail
From: cline@parashift.com
Sender: cline@parashift.com
Newsgroups: comp.lang.c++,comp.answers,news.answers,alt.comp.lang.learn.c-c++
Subject: C++ FAQ (part 06 of 12)
Summary: Please read this before posting to comp.lang.c++
Followup-To: comp.lang.c++
Reply-To: cline@parashift.com (Marshall Cline)
Distribution: world
Approved: news-answers-request@mit.edu
Expires: +1 month
Lines: 1343
Message-ID: <SJfB8.11123$5O.1715423403@newssvr12.news.prodigy.com>
NNTP-Posting-Host: 66.140.56.188
X-Complaints-To: abuse@prodigy.net
X-Trace: newssvr12.news.prodigy.com 1020626930 ST000 66.140.56.188 (Sun, 05 May 2002 15:28:50 EDT)
NNTP-Posting-Date: Sun, 05 May 2002 15:28:50 EDT
Organization: Prodigy Internet http://www.prodigy.com
X-UserInfo1: SCSGWXCEGZRCRVXXBZK\_RLAPJT@QDDMEPWXODMMHXMTWA]EPUW[AKK[J\]^HVKHG^EWZHBLO^[\NH_AZFWGN^\DHNVMX_DHHX[FSQKBOTS@@BP^]C@RHS_AGDDC[AJM_T[GZNRNZAY]GNCPBDYKOLK^_CZFWPGHZIXW@C[AFKBBQS@E@DAZ]VDFUNTQQ]FN
Date: Sun, 05 May 2002 19:28:50 GMT
Xref: senator-bedfellow.mit.edu comp.lang.c++:643624 comp.answers:49830 news.answers:229575 alt.comp.lang.learn.c-c++:121851

Archive-name: C++-faq/part06
Posting-Frequency: monthly
Last-modified: May 3, 2002
URL: http://www.parashift.com/c++-faq-lite/

AUTHOR: Marshall Cline / cline@parashift.com / 972-931-9470

COPYRIGHT: This posting is part of "C++ FAQ Lite."  The entire "C++ FAQ Lite"
document is Copyright(C)1991-2002 Marshall Cline, Ph.D., cline@parashift.com.
All rights reserved.  Copying is permitted only under designated situations.
For details, see section [1].

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.

C++-FAQ-Lite != C++-FAQ-Book: This document, C++ FAQ Lite, is not the same as
the C++ FAQ Book.  The book (C++ FAQs, Cline and Lomow, Addison-Wesley) is 500%
larger than this document, and is available in bookstores.  For details, see
section [3].

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

SECTION [12]: Assignment operators


[12.1] What is "self assignment"?

Self assignment is when someone assigns an object to itself.  For example,

 #include "Fred.hpp"    // Declares class Fred

 void userCode(Fred& x)
 {
   x = x;   // Self-assignment
 }

Obviously no one ever explicitly does a self assignment like the above, but
since more than one pointer or reference can point to the same object
(aliasing), it is possible to have self assignment without knowing it:

 #include "Fred.hpp"    // Declares class Fred

 void userCode(Fred& x, Fred& y)
 {
   x = y;   // Could be self-assignment if &x == &y
 }

 int main()
 {
   Fred z;
   userCode(z, z);
 }

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

[12.2] Why should I worry about "self assignment"?

If you don't worry about self assignment[12.1], you'll expose your users to
some very subtle bugs that have very subtle and often disastrous symptoms.  For
example, the following class will cause a complete disaster in the case of
self-assignment:

 class Wilma { };

 class Fred {
 public:
   Fred()                : p_(new Wilma())      { }
   Fred(const Fred& f)   : p_(new Wilma(*f.p_)) { }
  ~Fred()                { delete p_; }
   Fred& operator= (const Fred& f)
     {
       // Bad code: Doesn't handle self-assignment!
       delete p_;                // Line #1
       p_ = new Wilma(*f.p_);    // Line #2
       return *this;
     }
 private:
   Wilma* p_;
 };

If someone assigns a Fred object to itself, line #1 deletes both this->p_ and
f.p_ since *this and f are the same object.  But line #2 uses *f.p_, which is
no longer a valid object.  This will likely cause a major disaster.

The bottom line is that you the author of class Fred are responsible to make
sure self-assignment on a Fred object is innocuous[12.3].  Do not assume that
users won't ever do that to your objects.  It is your fault if your object
crashes when it gets a self-assignment.

Aside: the above Fred::operator= (const Fred&) has a second problem:     If an
exception is thrown[17] while evaluating new Wilma(*f.p_) (e.g., an
out-of-memory     exception[16.5] or an exception in Wilma's copy
    constructor[17.2]), this->p_ will be a dangling pointer -- it will
    point to memory that is no longer valid.  This can be solved by allocating
the     new objects before deleting the old objects.

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

[12.3] OK, OK, already; I'll handle self-assignment.  How do I do it?

You should worry about self assignment every time you create a class[12.2].
This does not mean that you need to add extra code to all your classes: as long
as your objects gracefully handle self assignment, it doesn't matter whether
you had to add extra code or not.

If you do need to add extra code to your assignment operator, here's a simple
and effective technique:

 Fred& Fred::operator= (const Fred& f)
 {
   if (this == &f) return *this;   // Gracefully handle self assignment[12.1]

   // Put the normal assignment duties here...

   return *this;
 }

This explicit test isn't always necessary.  For example, if you were to fix the
assignment operator in the previous FAQ[12.2] to handle exceptions thrown by
new[16.5] and/or exceptions thrown by the copy constructor[17.2] of class
Wilma, you might produce the following code.  Note that this code has the
(pleasant) side effect of automatically handling self assignment as well:

 Fred& Fred::operator= (const Fred& f)
 {
   // This code gracefully (albeit implicitly) handles self assignment[12.1]
   Wilma* tmp = new Wilma(*f.p_);   // It would be OK if an exception[17] got thrown here
   delete p_;
   p_ = tmp;
   return *this;
 }

In cases like the previous example (where self assignment is harmless but
inefficient), some programmers want to improve the efficiency of self
assignment by adding an otherwise unnecessary test, such as
"if (this == &f) return *this;".  It is generally the wrong tradeoff to make
self assignment more efficient by making the non-self assignment case less
efficient.  For example, adding the above if test to the Fred assignment
operator would make the non-self assignment case slightly less efficient (an
extra (and unnecessary) conditional branch).  If self assignment actually
occured once in a thousand times, the if would waste cycles 99.9% of the time.

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

SECTION [13]: Operator overloading


[13.1] What's the deal with operator overloading?

It allows you to provide an intuitive interface to users of your class, plus
makes it possible for templates[32.5] to work equally well with classes and
built-in/intrinsic types.

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

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

 #if 0

   // Without operator overloading:
   Fred add(Fred, Fred);
   Fred mul(Fred, Fred);

   Fred f(Fred a, Fred b, Fred c)
   {
     return add(add(mul(a,b), mul(b,c)), mul(c,a));    // Yuk...
   }

 #else

   // With operator overloading:
   Fred operator+ (Fred, Fred);
   Fred operator* (Fred, Fred);

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

 #endif

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

[13.2] What are the benefits of operator overloading?

By overloading standard operators on a class, you can exploit the intuition of
the users of that class.  This lets users program in the language of the
problem domain rather than in the language of the machine.

The ultimate goal is to reduce both the learning curve and the defect rate.

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

[13.3] What are some examples of operator overloading?

Here are a few of the many examples of operator overloading:
 * myString + yourString might concatenate two std::string objects
 * myDate++ might increment a Date object
 * a * b might multiply two Number objects
 * a[i] might access an element of an Array object
 * x = *p might dereference a "smart pointer" that actually "points" to a disk
   record -- it could actually seek to the location on disk where p "points"
   and return the appropriate record into x

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

[13.4] But operator overloading makes my class look ugly; isn't it supposed to
       make my code clearer?

Operator overloading makes life easier for the users of a class[13.2], not for
the developer of the class!

Consider the following example.

 class Array {
 public:
   int& operator[] (unsigned i);      // Some people don't like this syntax
   // ...
 };

 inline
 int& Array::operator[] (unsigned i)  // Some people don't like this syntax
 {
   // ...
 }

Some people don't like the keyword operator or the somewhat funny syntax that
goes with it in the body of the class itself.  But the operator overloading
syntax isn't supposed to make life easier for the developer of a class.  It's
supposed to make life easier for the users of the class:

 int main()
 {
   Array a;
   a[3] = 4;   // User code should be obvious and easy to understand...
 }

Remember: in a reuse-oriented world, there will usually be many people who use
your class, but there is only one person who builds it (yourself); therefore
you should do things that favor the many rather than the few.

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

[13.5] 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:
   int& elem(unsigned i)        { if (i > 99) error(); return data[i]; }
 private:
   int data[100];
 };

 int main()
 {
   Array a;
   a.elem(10) = 42;
   a.elem(12) += a.elem(13);
 }

Now the same logic is presented with operator overloading:

 class Array {
 public:
   int& operator[] (unsigned i) { if (i > 99) error(); return data[i]; }
 private:
   int data[100];
 };

 int main()
 {
   Array a;
   a[10] = 42;
   a[12] += a[13];
 }

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

[13.6] Can I overload operator== so it lets me compare two char[] using a
       string comparison?

No: at least one operand of any overloaded operator must be of some
user-defined type[25.10] (most of the time that means a class).

But even if C++ allowed you to do this, which it doesn't, you wouldn't want to
do it anyway since you really should be using a std::string-like class rather
than an array of char in the first place[17.5] since arrays are evil[32.1].

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

[13.7] 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 <cmath>).

By the way, operator^ can work for to-the-power-of, except it has the wrong
precedence and associativity.

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

[13.8] How do I create a subscript operator for a Matrix class?

Use operator() rather than operator[].

When you have multiple subscripts, the cleanest way to do it is with operator()
rather than with operator[].  The reason is that operator[] always takes
exactly one parameter, but operator() can take any number of parameters (in the
case of a rectangular matrix, two paramters are needed).

For example:

 class Matrix {
 public:
   Matrix(unsigned rows, unsigned cols);
   double& operator() (unsigned row, unsigned col);
   double  operator() (unsigned row, unsigned col) const;
   // ...
  ~Matrix();                              // Destructor
   Matrix(const Matrix& m);               // Copy constructor
   Matrix& operator= (const Matrix& m);   // Assignment operator
   // ...
 private:
   unsigned rows_, cols_;
   double* data_;
 };

 inline
 Matrix::Matrix(unsigned rows, unsigned cols)
   : rows_ (rows),
     cols_ (cols),
     data_ (new double[rows * cols])
 {
   if (rows == 0 || cols == 0)
     throw BadIndex("Matrix constructor has 0 size");
 }

 inline
 Matrix::~Matrix()
 {
   delete[] data_;
 }

 inline
 double& Matrix::operator() (unsigned row, unsigned col)
 {
   if (row >= rows_ || col >= cols_)
     throw BadIndex("Matrix subscript out of bounds");
   return data_[cols_*row + col];
 }

 inline
 double Matrix::operator() (unsigned row, unsigned col) const
 {
   if (row >= rows_ || col >= cols_)
     throw BadIndex("const Matrix subscript out of bounds");
   return data_[cols_*row + col];
 }

Then you can access an element of Matrix m using m(i,j) rather than m[i][j]:

 int main()
 {
   Matrix m(10,10);
   m(5,8) = 106.15;
   std::cout << m(5,8);
   // ...
 }

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

[13.9] Why shouldn't my Matrix class's interface look like an array-of-array?

Here's what this FAQ is really all about: Some people build a Matrix class that
has an operator[] that returns a reference to an Array object, and that Array
object has an operator[] that returns an element of the Matrix (e.g., a
reference to a double).  Thus they access elements of the matrix using syntax
like m[i][j] rather than syntax like m(i,j)[13.8].

The array-of-array solution obviously works, but it is less flexible than the
operator() approach[13.8].  Specifically, there are easy performance tuning
tricks that can be done with the operator() approach that are more difficult in
the [][] approach, and therefore the [][] approach is more likely to lead to
bad performance, at least in some cases.

For example, the easiest way to implement the [][] approach is to use a
physical layout of the matrix as a dense matrix that is stored in row-major
form (or is it column-major; I can't ever remember).  In contrast, the
operator() approach[13.8] totally hides the physical layout of the matrix, and
that can lead to better performance in some cases.

Put it this way: the operator() approach is never worse than, and sometimes
better than, the [][] approach.
 * The operator() approach is never worse because it is easy to implement the
   dense, row-major physical layout using the operator() approach, so when that
   configuration happens to be the optimal layout from a performance
   standpoint, the operator() approach is just as easy as the [][] approach
   (perhaps the operator() approach is a tiny bit easier, but I won't quibble
   over minor nits).
 * The operator() approach is sometimes better because whenever the optimal
   layout for a given application happens to be something other than dense,
   row-major, the implementation is often significantly easier using the
   operator() approach compared to the [][] approach.

As an example of when a physical layout makes a significant difference, a
recent project happened to access the matrix elements in columns (that is, the
algorithm accesses all the elements in one column, then the elements in
another, etc.), and if the physical layout is row-major, the accesses can
"stride the cache".  For example, if the rows happen to be almost as big as the
processor's cache size, the machine can end up with a "cache miss" for almost
every element access.  In this particular project, we got a 20% improvement in
performance by changing the mapping from the logical layout (row,column) to the
physical layout (column,row).

Of course there are many examples of this sort of thing from numerical methods,
and sparse matrices are a whole other dimension on this issue.  Since it is, in
general, easier to implement a sparse matrix or swap row/column ordering using
the operator() approach, the operator() approach loses nothing and may gain
something -- it has no down-side and a potential up-side.

Use the operator() approach[13.8].

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

[13.10] Should I design my classes from the outside (interfaces first) or from
        the inside (data first)? [UPDATED!]

[Recently rewrote the rationale for hiding nodes as inspired by a discussion
with Michael Lacher (in 4/02).]

From the outside!

A good interface provides a simplified view that is expressed in the vocabulary
of a user[7.3].  In the case of OO software, the interface is normally the set
of public methods of either a single class or a tight group of classes[14.2].

First think about what the object logically represents, not how you intend to
physically build it.  For example, suppose you have a Stack class that will be
built by containing a LinkedList:

 class Stack {
 public:
   // ...
 private:
   LinkedList list_;
 };

Should the Stack have a get() method that returns the LinkedList? Or a set()
method that takes a LinkedList? Or a constructor that takes a LinkedList?
Obviously the answer is No, since you should design your interfaces from the
outside-in.  I.e., users of Stack objects don't care about LinkedLists; they
care about pushing and popping.

Now for another example that is a bit more subtle.  Suppose class LinkedList is
built using a linked list of Node objects, where each Node object has a pointer
to the next Node:

 class Node { /*...*/ };

 class LinkedList {
 public:
   // ...
 private:
   Node* first_;
 };

Should the LinkedList class have a get() method that will let users access the
first Node? Should the Node object have a get() method that will let users
follow that Node to the next Node in the chain? In other words, what should a
LinkedList look like from the outside? Is a LinkedList really a chain of Node
objects? Or is that just an implementation detail? And if it is just an
implementation detail, how will the LinkedList let users access each of the
elements in the LinkedList one at a time?

The key insight is the realization that a LinkedList is not a chain of Nodes.
That may be how it is built, but that is not what it is.  What it is is a
sequence of elements.  Therefore the LinkedList abstraction should provide a
"LinkedListIterator" class as well, and that "LinkedListIterator" might have an
operator++ to go to the next element, and it might have a get()/set() pair to
access its value stored in the Node (the value in the Node element is solely
the responsibility of the LinkedList user, which is why there is a get()/set()
pair that allows the user to freely manipulate that value).

Starting from the user's perspective, we might want our LinkedList class to
support operations that look similar to accessing an array using pointer
arithmetic:

 void userCode(LinkedList& a)
 {
   for (LinkedListIterator p = a.begin(); p != a.end(); ++p)
     std::cout << *p << '\n';
 }

To implement this interface, LinkedList will need a begin() method and an end()
method.  These return a "LinkedListIterator" object.  The "LinkedListIterator"
will need a method to go forward, ++p; a method to access the current element,
*p; and a comparison operator, p != a.end().

The code follows.  The important thing to notice is that LinkedList does not
have any methods that let users access Nodes.  Nodes are an implementation
technique that is completely buried.  This makes the LinkedList class safer (no
chance a user will mess up the invariants and linkages between the various
nodes), easier to use (users don't need to expend extra effort keeping the
node-count equal to the actual number of nodes, or any other infrastructure
stuff), and more flexible (by changing a single typedef, users could change
their code from using LinkedList to some other list-like class and the bulk of
their code would compile cleanly and hopefully with improved performance
characteristics).

 #include <cassert>    // Poor man's exception handling

 class LinkedListIterator;
 class LinkedList;

 class Node {
   // No public members; this is a "private class"
   friend LinkedListIterator;   // A friend class[14]
   friend LinkedList;
   Node* next_;
   int elem_;
 };

 class LinkedListIterator {
 public:
   bool operator== (LinkedListIterator i) const;
   bool operator!= (LinkedListIterator i) const;
   void operator++ ();   // Go to the next element
   int& operator*  ();   // Access the current element
 private:
   LinkedListIterator(Node* p);
   Node* p_;
   friend LinkedList;  // so LinkedList can construct a LinkedListIterator
 };

 class LinkedList {
 public:
   void append(int elem);    // Adds elem after the end
   void prepend(int elem);   // Adds elem before the beginning
   // ...
   LinkedListIterator begin();
   LinkedListIterator end();
   // ...
 private:
   Node* first_;
 };

Here are the methods that are obviously inlinable (probably in the same header
file):

 inline bool LinkedListIterator::operator== (LinkedListIterator i) const
 {
   return p_ == i.p_;
 }

 inline bool LinkedListIterator::operator!= (LinkedListIterator i) const
 {
   return p_ != i.p_;
 }

 inline void LinkedListIterator::operator++()
 {
   assert(p_ != NULL);  // or if (p_==NULL) throw ...
   p_ = p_->next_;
 }

 inline int& LinkedListIterator::operator*()
 {
   assert(p_ != NULL);  // or if (p_==NULL) throw ...
   return p_->elem_;
 }

 inline LinkedListIterator::LinkedListIterator(Node* p)
   : p_(p)
 { }

 inline LinkedListIterator LinkedList::begin()
 {
   return first_;
 }

 inline LinkedListIterator LinkedList::end()
 {
   return NULL;
 }

Conclusion: The linked list had two different kinds of data.  The values of the
elements stored in the linked list are the responsibility of the user of the
linked list (and only the user; the linked list itself makes no attempt to
prohibit users from changing the third element to 5), and the linked list's
infrastructure data (next pointers, etc.), whose values are the responsibility
of the linked list (and only the linked list; e.g., the linked list does not
let users change (or even look at!) the various next pointers).

Thus the only get()/set() methods were to get and set the elements of the
linked list, but not the infrastructure of the linked list.  Since the linked
list hides the infrastructure pointers/etc., it is able to make very strong
promises regarding that infrastructure (e.g., if it was a doubly linked list,
it might guarantee that every forward pointer was matched by a backwards
pointer from the next Node).

So, we see here an example of where the values of some of a class's data is the
responsibility of users (in which case the class needs to have get()/set()
methods for that data) but the data that the class wants to control does not
necessarily have get()/set() methods.

Note: the purpose of this example is not to show you how to write a linked-list
class.  In fact you should not "roll your own" linked-list class since you
should use one of the "container classes" provided with your compiler.  Ideally
you'll use one of the standard container classes[33.1] such as the std::list<T>
template.

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

SECTION [14]: Friends


[14.1] 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 friend and member functions of a class (else you may need
to get permission from the owner of the other pieces when you want to update
your own class).

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

[14.2] Do friends violate encapsulation?

No! 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 amount of code that needs direct access to
a data structure; you've simply reshuffled the code into two classes instead of
one).  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.
People who don't understand this often make naive efforts to avoid using
friendship in situations like the above, and often they actually destroy
encapsulation.  They either use public data (grotesque!), or they make the data
accessible between the halves via public get() and set() member functions.
Having a public get() and set() member function 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() member functions are almost as
bad as public data: they hide (only) the name of the private datum, but they
don't hide the existence of the private datum.

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
don't violate the encapsulation barrier: along with the class's member
functions, they are the encapsulation barrier.

(Many people think of a friend function as something outside the class.
Instead, try thinking of a friend function as part of the class's public
interface.  A friend function in the class declaration doesn't violate
encapsulation any more than a public member function violates encapsulation:
both have exactly the same authority with respect to accessing the class's
non-public parts.)

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

[14.3] What are some advantages/disadvantages of using friend functions?

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

Member functions and friend functions are equally privileged (100% vested).
The major difference is that a friend function is called like f(x), while a
member function is called like x.f().  Thus the ability to choose between
member functions (x.f()) and friend functions (f(x)) allows a 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[20] member
function.  This is called the Virtual Friend Function Idiom[15.9].  For
example:

 class Base {
 public:
   friend void f(Base& b);
   // ...
 protected:
   virtual void do_f();
   // ...
 };

 inline void f(Base& b)
 {
   b.do_f();
 }

 class Derived : public Base {
 public:
   // ...
 protected:
   virtual void do_f();  // "Override" the behavior of f(Base& b)
   // ...
 };

 void userCode(Base& b)
 {
   f(b);
 }

The statement f(b) in userCode(Base&) will invoke b.do_f(), which is
virtual[20].  This means that Derived::do_f() will get control if b is actually
a object of class Derived.  Note that Derived overrides the behavior of the
protected virtual[20] member function do_f(); it does not have its own
variation of the friend function, f(Base&).

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

[14.4] What does it mean that "friendship isn't inherited, transitive, or
       reciprocal"?

Just because I grant you friendship access to me doesn't automatically grant
your kids access to me, doesn't automatically grant your friends access to me,
and doesn't automatically grant me access to you.
 * I don't necessarily trust the kids of my friends.  The privileges of
   friendship aren't inherited.  Derived classes of a friend aren't necessarily
   friends.  If class Fred declares that class Base is a friend, classes
   derived from Base don't have any automatic special access rights to Fred
   objects.
 * I don't necessarily trust the friends of my friends.  The privileges of
   friendship aren't transitive.  A friend of a friend isn't necessarily a
   friend.  If class Fred declares class Wilma as a friend, and class Wilma
   declares class Betty as a friend, class Betty doesn't necessarily have any
   special access rights to Fred objects.
 * You don't necessarily trust me simply because I declare you my friend.  The
   privileges of friendship aren't reciprocal.  If class Fred declares that
   class Wilma is a friend, Wilma objects have special access to Fred objects
   but Fred objects do not automatically have special access to Wilma objects.

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

[14.5] 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
functions allow the Fred parameter 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 should be defined as a friend rather than
a member if you want to allow aFloat + aComplex as well (member functions don't
allow promotion of the left hand argument, 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 [15]: Input/output via <iostream> and <cstdio>


[15.1] Why should I use <iostream> instead of the traditional <cstdio>?

Increase type safety, reduce errors, allow extensibility, and provide
inheritability.

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()):
 * More type-safe: With <iostream>, the type of object being I/O'd is known
   statically by the compiler.  In contrast, <cstdio> uses "%" fields to figure
   out the types dynamically.
 * Less error prone: With <iostream>, there are no redundant "%" tokens that
   have to be consistent with the actual objects being I/O'd.  Removing
   redundancy removes a class of errors.
 * Extensible: The C++ <iostream> mechanism allows new user-defined types to be
   I/O'd without breaking existing code.  Imagine the chaos if everyone was
   simultaneously adding new incompatible "%" fields to printf() and
   scanf()?!).
 * Inheritable: The C++ <iostream> mechanism is built from real classes such as
   std::ostream and std::istream.  Unlike <cstdio>'s FILE*, these are real
   classes and hence inheritable.  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.

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

[15.2] Why does my program go into an infinite loop when someone enters an
       invalid input character?

For example, suppose you have the following code that reads integers from
std::cin:

 #include <iostream>

 int main()
 {
   std::cout << "Enter numbers separated by whitespace (use -1 to quit): ";
   int i = 0;
   while (i != -1) {
     std::cin >> i;        // BAD FORM -- See comments below
     std::cout << "You entered " << i << '\n';
   }
 }

The problem with this code is that it lacks any checking to see if someone
entered an invalid input character.  In particular, if someone enters something
that doesn't look like an integer (such as an 'x'), the stream std::cin goes
into a "failed state," and all subsequent input attempts return immediately
without doing anything.  In other words, the program enters an infinite loop;
if 42 was the last number that was successfully read, the program will print
the message You entered 42 over and over.

An easy way to check for invalid input is to move the input request from the
body of the while loop into the control-expression of the while loop.  E.g.,

 #include <iostream>

 int main()
 {
   std::cout << "Enter a number, or -1 to quit: ";
   int i = 0;
   while (std::cin >> i) {    // GOOD FORM
     if (i == -1) break;
     std::cout << "You entered " << i << '\n';
   }
 }

This will cause the while loop to exit either when you hit end-of-file, or when
you enter a bad integer, or when you enter -1.

(Naturally you can eliminate the break by changing the while loop expression
from while (std::cin >> i) to while ((std::cin >> i) && (i != -1)), but that's
not really the point of this FAQ since this FAQ has to do with iostreams rather
than generic structured programming guidelines.)

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

[15.3] How does that funky while (std::cin >> foo) syntax work?

See the previous FAQ[15.2] for an example of the "funky while (std::cin >> foo)
syntax."

The expression (std::cin >> foo) calls the appropriate operator>> (for example,
it calls the operator>> that takes an std::istream on the left and, if foo is
of type int, an int& on the right).  The std::istream operator>> functions
return their left argument by convention, which in this case means it will
return std::cin.  Next the compiler notices that the returned std::istream is
in a boolean context, so it converts that std::istream into a boolean.

To convert an std::istream into a boolean, the compiler calls a member function
called std::istream::operator void*().  This returns a void* pointer, which is
in turn converted to a boolean (NULL becomes false, any other pointer becomes
true).  So in this case the compiler generates a call to
std::cin.operator void*(), just as if you had casted it explicitly such as
(void*) std::cin.

The operator void*() cast operator returns some non-NULL pointer if the stream
is in a good state, or NULL if it's in a failed state.  For example, if you
read one too many times (e.g., if you're already at end-of-file), or if the
actual info on the input stream isn't valid for the type of foo (e.g., if foo
is an int and the data is an 'x' character), the stream will go into a failed
state and the cast operator will return NULL.

The reason operator>> doesn't simply return a bool (or void*) indicating
whether it succeeded or failed is to support the "cascading" syntax:

   std::cin >> foo >> bar;

The operator>> is left-associative, which means the above is parsed as:

   (std::cin >> foo) >> bar;

In other words, if we replace operator>> with a normal function name such as
readFrom(), this becomes the expression:

   readFrom( readFrom(std::cin, foo), bar);

As always, we begin evaluating at the innermost expression.  Because of the
left-associativity of operator>>, this happens to be the left-most expression,
std::cin >> foo.  This expression returns std::cin (more precisely, it returns
a reference to its left-hand argument) to the next expression.  The next
expression also returns (a reference to) std::cin, but this second reference is
ignored since it's the outermost expression in this "expression statement."

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

[15.4] Why does my input seem to process past the end of file?

Because the eof state may not get set until after a read is attempted past the
end of file.  That is, reading the last byte from a file might not set the eof
state.  E.g., suppose the input stream is mapped to a keyboard -- in that case
it's not even theoretically possible for the C++ library to predict whether or
not the character that the user just typed will be the last character.

For example, the following code might have an off-by-one error with the count
i:

 int i = 0;
 while (! std::cin.eof()) {   // WRONG! (not reliable)
   std::cin >> x;
   ++i;
   // Work with x ...
 }

What you really need is:

 int i = 0;
 while (std::cin >> x) {      // RIGHT! (reliable)
   ++i;
   // Work with x ...
 }

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

[15.5] Why is my program ignoring my input request after the first iteration?

Because the numerical extractor leaves non-digits behind in the input buffer.

If your code looks like this:

 char name[1000];
 int age;

 for (;;) {
   std::cout << "Name: ";
   std::cin >> name;
   std::cout << "Age: ";
   std::cin >> age;
 }

What you really want is:

 for (;;) {
   std::cout << "Name: ";
   std::cin >> name;
   std::cout << "Age: ";
   std::cin >> age;
   std::cin.ignore(INT_MAX, '\n');
 }

Of course you might want to change the for (;;) statement to while (std::cin),
but don't confuse that with skipping the non-numeric characters at the end of
the loop via the line: std::cin.ignore(...);.

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

[15.6] How can I provide printing for my class Fred?

Use operator overloading[13] to provide a friend[14] left-shift operator,
operator<<.

 #include <iostream>

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

 std::ostream& operator<< (std::ostream& o, const Fred& fred)
 {
   return o << fred.i_;
 }

 int main()
 {
   Fred f;
   std::cout << "My Fred object: " << f << "\n";
 }

We use a non-member function (a friend[14] in this case) since the Fred object
is the right-hand operand of the << operator.  If the Fred object was supposed
to be on the left hand side of the << (that is, myFred << std::cout rather than
std::cout << myFred), we could have used a member function named operator<<.

Note that operator<< returns the stream.  This is so the output operations can
be cascaded[15.3].

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

[15.7] But shouldn't I always use a printOn() method rather than a friend
       function?

No.

The usual reason people want to always use a printOn() method rather than a
friend function is because they wrongly believe that friends violate
encapsulation and/or that friends are evil.  These beliefs are naive and wrong:
when used properly, friends can actually enhance encapsulation[14.2].

This is not to say that the printOn() method approach is never useful.  For
example, it is useful when providing printing for an entire hierarchy of
classes[15.9].  But if you use a printOn() method, it should normally be
protected, not public.

For completeness, here is "the printOn() method approach." The idea is to have
a member function (often called printOn() that does the actual printing, then
have operator<< call that printOn() method.  When it is done wrongly, the
printOn() method is public so operator<< doesn't have to be a friend -- it can
be a simple top-level function that is neither a friend nor a member of the
class.  Here's some sample code:

 #include <iostream>

 class Fred {
 public:
   void printOn(std::ostream& o) const;
   // ...
 };

 // operator<< can be declared as a non-friend [NOT recommended!]
 std::ostream& operator<< (std::ostream& o, const Fred& fred);

 // The actual printing is done inside the printOn() method [NOT recommended!]
 void Fred::printOn(std::ostream& o) const
 {
   // ...
 }

 // operator<< calls printOn() [NOT recommended!]
 std::ostream& operator<< (std::ostream& o, const Fred& fred)
 {
   fred.printOn(o);
   return o;
 }

People wrongly assume that this reduces maintenance cost "since it avoids
having a friend function." This is a wrong assumption because:

 1. The member-called-by-top-level-function approach has zero benefit in terms
    of maintenance cost. Let's say it takes N lines of code to do the actual
    printing.  In the case of a friend function, those N lines of code will
    have direct access to the class's private/protected parts, which means
    whenever someone changes the class's private/protected parts, those N lines
    of code will need to be scanned and possibly modified, which increases the
    maintenance cost.  However using the printOn() method doesn't change this
    at all: we still have N lines of code that have direct access to the
    class's private/protected parts.  Thus moving the code from a friend
    function into a member function does not reduce the maintenance cost at
    all.  Zero reduction.  No benefit in maintenance cost.  (If anything it's a
    bit worse with the printOn() method since you now have more lines of code
    to maintain since you have an extra function that you didn't have before.)

 2. The member-called-by-top-level-function approach makes the class harder to
    use, particularly by programmers who are not also class designers. The
    approach exposes a public method that programmers are not supposed to call.
    When a programmer reads the public methods of the class, they'll see two
    ways to do the same thing.  The documentation would need to say something
    like, "This does exactly the same as that, but don't use this; instead use
    that." And the average programmer will say, "Huh? Why make the method
    public if I'm not supposed to use it?" In reality the only reason the
    printOn() method is public is to avoid granting friendship status to
    operator<<, and that is a notion that is somewhere between subtle and
    incomprehensible to a programmer who simply wants to use the class.

Net: the member-called-by-top-level-function approach has a cost but no
benefit.  Therefore it is, in general, a bad idea.

Note: if the printOn() method is protected or private, the second objection
doesn't apply.  There are cases when that approach is reasonable, such as when
providing printing for an entire hierarchy of classes[15.9].  Note also that
when the printOn() method is non-public, operator<< needs to be a friend.

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

[15.8] How can I provide input for my class Fred?

Use operator overloading[13] to provide a friend[14] right-shift operator,
operator>>.  This is similar to the output operator[15.6], except the parameter
doesn't have a const[18]: "Fred&" rather than "const Fred&".

 #include <iostream>

 class Fred {
 public:
   friend std::istream& operator>> (std::istream& i, Fred& fred);
   // ...
 private:
   int i_;    // Just for illustration
 };

 std::istream& operator>> (std::istream& i, Fred& fred)
 {
   return i >> fred.i_;
 }

 int main()
 {
   Fred f;
   std::cout << "Enter a Fred object: ";
   std::cin >> f;
   // ...
 }

Note that operator>> returns the stream.  This is so the input operations can
be cascaded and/or used in a while loop or if statement[15.3].

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

[15.9] How can I provide printing for an entire hierarchy of classes?

Provide a friend[14] operator<<[15.6] that calls a protected virtual[20]
function:

 class Base {
 public:
   friend std::ostream& operator<< (std::ostream& o, const Base& b);
   // ...
 protected:
   virtual void printOn(std::ostream& o) const;
 };

 inline std::ostream& operator<< (std::ostream& o, const Base& b)
 {
   b.printOn(o);
   return o;
 }

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

The end result is that operator<< acts as if it was dynamically bound, even
though it's a friend[14] function.  This is called the Virtual Friend Function
Idiom.

Note that derived classes override printOn(std::ostream&) const.  In
particular, they do not provide their own operator<<.

Naturally if Base is an ABC[22.3], Base::printOn(std::ostream&) const can be
declared pure virtual[22.4] using the "= 0" syntax.

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

[15.10] How can I "reopen" std::cin and std::cout in binary mode under DOS
        and/or OS/2?

This is implementation dependent.  Check with your compiler's documentation.

For example, suppose you want to do binary I/O using std::cin and std::cout.
Suppose further that your operating system (such as DOS or OS/2) insists on
translating "\r\n" into "\n" on input from std::cin, and "\n" to "\r\n" on
output to std::cout or std::cerr.

Unfortunately there is no standard way to cause std::cin, std::cout, and/or
std::cerr to be opened in binary mode.  Closing the streams and attempting to
reopen them in binary mode might have unexpected or undesirable results.

On systems where it makes a difference, the implementation might provide a way
to make them binary streams, but you would have to check the manuals to find
out.

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

[15.11] How can I tell {if a key, which key} was pressed before the user
        presses the ENTER key? [NEW!]

[Recently created inspired by a posting by Alan Didey (in 5/02).]

This is not a standard C++ feature -- C++ doesn't even require your system to
have a keyboard!.  That means every operating system and vendor does it
somewhat differently.

Please read the documentation that came with your compiler for details on your
particular installation.

(By the way, the process on UNIX typically has two steps: first set the
terminal to single-character mode
<http://www.faqs.org/faqs/unix-faq/programmer/faq/>, then use either select()
or poll() to test if a key was pressed.  You might be able to adapt this code
<http://ccwf.cc.utexas.edu/~apoc/programs/c/kbhit.c>.)

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

[15.12] How can make it so keys pressed by users are not echoed on the screen?
        [NEW!]

[Recently created (in 5/02).]

This is not a standard C++ feature -- C++ doesn't even require your system to
have a keyboard or a screen.  That means every operating system and vendor does
it somewhat differently.

Please read the documentation that came with your compiler for details on your
particular installation.

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

[15.13] How can I move the cursor around on the screen? [NEW!]

[Recently created (in 5/02).]

This is not a standard C++ feature -- C++ doesn't even require your system to
have a screen.  That means every operating system and vendor does it somewhat
differently.

Please read the documentation that came with your compiler for details on your
particular installation.

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

[15.14] Why can't I open a file in a different directory such as "..\test.dat"?

Because "\t" is a tab character.

You should use forward slashes in your filenames, even on operating systems
that use backslashes (DOS, Windows, OS/2, etc.).  For example:

 #include <iostream>
 #include <fstream>

 int main()
 {
   #if 1
     std::ifstream file("../test.dat");  // RIGHT!
   #else
     std::ifstream file("..\test.dat");  // WRONG!
   #endif

   // ...
 }

Remember, the backslash ("\") is used in string literals to create special
characters: "\n" is a newline, "\b" is a backspace, and "\t" is a tab, "\a" is
an "alert", "\v" is a vertical-tab, etc.  Therefore the file name
"\version\next\alpha\beta\test.dat" is interpreted as a bunch of very funny
characters.  To be safe, use "/version/next/alpha/beta/test.dat" instead, even
on systems that use a "\" as the directory separator.  This is because the
library routines on these operating systems handle "/" and "\" interchangeably.

Of course you could use "\\version\\next\\alpha\\beta\\test.dat", but that
might hurt you (there's a non-zero chance you'll forget one of the "\"s, a
rather subtle bug since most people don't notice it) and it can't help you
(there's no benefit for using "\\" over "/").  Besides "/" is more portable
since it works on all flavors of Unix, Plan 9, Inferno, all Windows, OS/2,
etc., but "\\" works only on a subset of that list.  So "\\" costs you
something and gains you nothing: use "/" instead.

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

[15.15] How do I convert a value (a number, for example) to a std::string?

There are two easy ways to do this: you can use the <cstdio> facilities or the
<iostream> library.  In general, you should prefer the <iostream>
library[15.1].

The <iostream> library allows you to convert pretty much anything to a
std::string using the following syntax (the example converts a double, but you
could substitute pretty much anything that prints using the << operator):

 #include <iostream>
 #include <sstream>
 #include <string>

 std::string convertToString(double x)
 {
   std::ostringstream o;
   if (o << x)
     return o.str();
   // some sort of error handling goes here...
   return "conversion error";
 }

The std::ostringstream object o offers formatting facilities just like those
for std::cout.  You can use manipulators and format flags to control the
formatting of the result, just as you can for other std::cout.

In this example, we insert x into o via the overloaded insertion operator, <<.
This invokes the iostream formatting facilities to convert x into a
std::string.  The if test[15.3] makes sure the conversion works correctly -- it
should always succeed for built-in/intrinsic types, but the if test is good
style.

The expression os.str() returns the std::string that contains whatever has been
inserted into stream o, in this case the string value of x.

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

[15.16] How do I convert a std::string to a number?

There are two easy ways to do this: you can use the <cstdio> facilities or the
<iostream> library.  In general, you should prefer the <iostream>
library[15.1].

The <iostream> library allows you to convert a std::string to pretty much
anything using the following syntax (the example converts a double, but you
could substitute pretty much anything that can be read using the >> operator):

 #include <iostream>
 #include <sstream>
 #include <string>

 double convertFromString(const std::string& s)
 {
   std::istringstream i(s);
   double x;
   if (i >> x)
     return x;
   // some sort of error handling goes here...
   return 0.0;
 }

The std::istringstream object i offers formatting facilities just like those
for std::cin.  You can use manipulators and format flags to control the
formatting of the result, just as you can for other std::cin.

In this example, we initialize the std::istringstream i passing the std::string
s (for example, s might be the string "123.456"), then we extract i into x via
the overloaded extraction operator, >>.  This invokes the iostream formatting
facilities to convert as much of the string as possible/appropriate based on
the type of x.

The if test[15.3] makes sure the conversion works correctly.  For example, if
the string contains characters that are inappropriate for the type of x, the if
test will fail.

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

