Learn more about IndiaStudyChannel
Install Alexa Toolbar
and earn more...
 
Communities Members BookmarksPolls Fresher Jobs Funny Photos B.Tech Projects New Member FAQ  



My Profile
Active Members
TodayLast 7 Days more...



Awards & Gifts
Online Exams

Fresher Jobs


Our fresher job section is exclusively for fresh graduates! Find jobs for freshers in major Indian cities including Bangalore, Chennai, Hyderabad, Pune or Kochi

Resources


Find educational articles, blogs, discussion threads and other resources.

Colleges


Find details about any college in India or search for courses.

website counter



c++


Posted Date: 16 May 2008    Resource Type: Articles/Knowledge Sharing    Category: Computer & Technology
Author: sri phani kumariMember Level: Gold    
Rating: Points: 2



[7.1] 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 computerscience 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 i + j or i++, 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.

You can imagine that int is a class that has member functions called operator++, etc. (int isn't really a class, but the basic analogy is this: a class is a type, much like int is a type.)

Note: a C programmer can think of a class as a C struct whose members default to private. But if that's all you think of a class, then you probably need to experience a personal paradigm shift.

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

[7.2] 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 OO/C++, "object" usually means "an instance of a class." Thus a class defines the behavior of possibly many objects (instances).

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

[7.3] When is an interface "good"?

When it provides a simplified view of a chunk of software, and it is expressed in the vocabulary of a user (where a "chunk" is normally a class or a tight group of classes[14.2], and a "user" is another developer rather than the ultimate customer).
* The "simplified view" means unnecessary details are intentionally hidden.
This reduces the user's defect-rate.
* The "vocabulary of users" means users don't need to learn a new set of words
and concepts. This reduces the user's learning curve.

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

[7.4] What is encapsulation?

Preventing unauthorized access to some piece of information or functionality.

The key money-saving insight is to separate the volatile part of some chunk of software from the stable part. Encapsulation puts a firewall around the chunk, which prevents other chunks from accessing the volatile parts; other chunks can only access the stable parts. This prevents the other chunks from breaking if (when!) the volatile parts are changed. In context of OO software, a "chunk" is normally a class or a tight group of classes[14.2].

The "volatile parts" are the implementation details. If the chunk is a single class, the volatile part is normally encapsulated using the private: and/or protected: keywords[19.5]. If the chunk is a tight group of classes[14.2],
encapsulation can be used to deny access to entire classes in that group. Inheritance[19] can also be used as a form of encapsulation[22.2].

The "stable parts" are the interfaces. A good interface provides a simplified view in the vocabulary of a user[7.3], and is designed from the outside-in[13.10] (here a "user" means another developer, not the end-user who
buys the completed application). If the chunk is a single class, the interface is simply the class's public: member functions and friend[14] functions. If the chunk is a tight group of classes[14.2], the interface can include several
of the classes in the chunk.

Designing a clean interface and separating that interface from its implementation[22.1] merely allows users to use the interface. But encapsulating (putting "in a capsule") the implementation forces users to use the interface.

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

[7.5] How does C++ help with the tradeoff of safety vs. usability?

In C, encapsulation[7.4] was accomplished by making things static in a compilation unit or module. This prevented another module from accessing the static stuff. (By the way, that use is now deprecated: don't do that in C++.)

Unfortunately this approach doesn't support multiple instances of the data, since there is no direct support for making multiple instances of a module's static data. If multiple instances were needed in C, programmers typically
used a struct. But unfortunately C structs don't support encapsulation[7.4]. This exacerbates the tradeoff between safety (information hiding) and usability (multiple instances).

In C++, you can have both multiple instances and encapsulation via a class. The public: part of a class contains the class's interface, which normally consists of the class's public: member functions and its friend[14] functions.
The private: and/or protected:[19.5] parts of a class contain the class's implementation, which is typically where the data lives.

The end result is like an "encapsulated struct." This reduces the tradeoff between safety (information hiding) and usability (multiple instances).
==============================================================================

[7.6] How can I prevent other programmers from violating encapsulation by seeing the private parts of my class?

Not worth the effort -- encapsulation is for code, not people.

It doesn't violate encapsulation for a programmer to see the private: and/or protected:[19.5] parts of your class, so long as they don't write code that somehow depends on what they saw. In other words, encapsulation doesn't
prevent people from knowing about the inside of a class; it prevents the code they write from becoming dependent on the insides of the class. Your company doesn't have to pay a "maintenance cost" to maintain the gray matter between
your ears; but it does have to pay a maintenance cost to maintain the code that comes out of your finger tips. What you know as a person doesn't increase maintenance cost, provided the code they write depends on the interface rather
than the implementation.

Besides, this is rarely if ever a problem. I don't know any programmers who have intentionally tried to access the private parts of a class. "My recommendation in such cases would be to change the programmer, not the code"
[James Kanze; used with permission].

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

[7.7] Is Encapsulation a Security device?

No.

Encapsulation != security.

Encapsulation prevents mistakes, not espionage.

============================================================================
[7.8] 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.

OK, enough of that squeaky clean techno talk. Emotionally, most developers make a strong distinction between a class and a struct. A struct simply feels like an open pile of bits with very little in the way of encapsulation or functionality. A class feels like a living and responsible member of society with intelligent services, a strong encapsulation barrier, and a well defined interface. Since that's the connotation most people already have, you should probably use the struct keyword if you h ave a class that has very few methods and has public data (such things do exist in well designed systems!), but otherwise you should probably use the class keyword.

============================================================================
SECTION [8]: References


[8.1] 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;
}

int 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 vice versa.

OK. That's how you should think of references as a programmer. Now, at the risk of confusing you by giving you a different perspective, here's how references are implemented. Underneath it all, a reference i to object x is
typically the machine address of the object x. But when the programmer says i++, the compiler generates code that increments x. In particular, the address bits that the compiler uses to find x are not changed. A C programmer will
think of this as if you used the C style pass-by-pointer, with the syntactic variant of (1) moving the & from the caller into the callee, and (2) eliminating the *s. In other words, a C programmer will think of i as a macro
for (*p), where p is a pointer to x (e.g., the compiler automatically dereferences the underlying pointer; i++ is changed to (*p)++; i = 7 is automatically changed to *p = 7).

Important note: Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object. It is not a
pointer to the object, nor a copy of the object. It is the object.

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

[8.2] What happens if you assign to a reference?

You change the state of the referent (the referent is the object to which the reference refers).

Remember: the reference is the referent, so changing the reference changes the state of the referent. In compiler writer lingo, a reference is an "lvalue" (something that can appear on the left hand side of an assignment operator).

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

[8.3] What happens if you return a reference?

The function call can appear on the left hand side of an assignment operator.

This ability may seem strange at first. For example, no one thinks the expression f() = 7 makes sense. Yet, if a is an object of class Array, most people think that a[i] = 7 makes sense even though a[i] is really just a function call in disguise (it calls Array::operator[](int), which is the subscript operator for class Array).

class Array {
public:
int size() const;
float& operator[] (int index);
// ...
};

int main()
{
Array a;
for (int i = 0; i < a.size(); ++i)
a[i] = 7; // This line invokes Array::operator[](int)
}

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

[8.4] How can you reseat a reference to make it refer to a different object?

No way.

You can't separate the reference from the referent.

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 identity; taking the address of a reference gives you the address of the referent; remember: the reference is its referent).

In that sense, a reference is similar to a const pointer[18.5] such as int* const p (as opposed to a pointer to const[18.4] such as const int* p). In spite of the gross similarity, please don't confuse references with pointers; they're not at all the same.

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

[8.5] 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 pointers whenever you don't need "reseating"[8.4]. 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 pointer).

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 y. E.g., programmers should write codein the language of the problem rather than the language of the machine.

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

SECTION [9]: Inline functions


[9.1] 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 #define 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").

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

[9.2] How can inline functions help with the tradeoff of safety vs. speed?

In straight C, you can achieve "encapsulated structs" by putting a void* in a struct, in which case the void* points to the real data that is unknown to users of the struct. Therefore users of the struct don't know how to interpret
the stuff pointed to by the vo id*, but the access functions cast the void* tothe approprate hidden type. This gives a form of encapsulation.

Unfortunately it 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, anyone and everyone would be able to get direct access since
they would of necessity know how to interpret the stuff pointed to by the void*; this would make it difficult to change the underlying data structure).

Function call overhead is small, but can add up. C++ classes allow function calls to be expanded inline. This lets you have the safety of encapsulation along with the speed of direct access. Furthermore the parameter types of these inline functions are checked by the compiler, an improvement over C's #define macros.

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

[9.3] Why should I use inline functions? Why not just use plain old #define macros? [UPDATED!]

Because #define macros are evil[9.3], evil[34.1], evil[34.2], evil[34.3].

Unlike #define macros, inline functions avoid infamous macro errors since inline functions always evaluate every argument exactly once. In other words, invoking an inline function is semantically just like invoking a regular
function, only faster:

// A macro that returns the absolute value of i
#define unsafe(i) \
( (i) >= 0 ? (i) : -(i) )

// An inline function that returns the absolute value of i
inline
int safe(int i)
{
return i >= 0 ? i : -i;
}

int f();

void userCode(int x)
{
int ans;

ans = unsafe(x++); // Error! x is incremented twice
ans = unsafe(f()); // Danger! f() is called twice

ans = safe(x++); // Correct! x is incremented once
ans = safe(f()); // Correct! f() is called once
}

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 have to.

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

[9.4] How do you tell the compiler to make a non-member function inline?

When you declare an inline function, it looks just like a normal function:

void f(int i, char c);

But when you define an inline function, you prepend the function's definition
with the keyword inline, and you put the definition into a header file:

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

Note: It's imperative that the function's definition (the part between the {...}) be placed in a header file, unless the function is used only in a single .cpp file. In particular, if you put the inline function's definition into a
.cpp file and you call it from some other .cpp file, you'll get an "unresolved external" error from the linker.

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

[9.5] How do you tell the compiler to make a member function inline?

When you declare an inline member function, it looks just like a normal member function:

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

But when you define an inline member function, you prepend the member function's definition with the keyword inline, and you put the definition into a header file:

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

It's usually imperative that the function's definition (the part between the {...}) be placed in a header file. If you put the inline function's definition into a .cpp file, and if it is called from some other .cpp file, you'll get an "unresolved external" error from the linker.

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

[9.6] Is there another way to tell the compiler to make a member function
inline?

Yep: define the member function in the class body itself:

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

Although this is easier on the person who writes the class, it's harder on all the readers since it mixes "what" a class does with "how" it does them. Because of this mixture, we normally prefer to define member functions outside the class body with the inline keyword[9.5]. The insight that makes sense of this: 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.

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

[9.7] Are inline functions guaranteed to make your performance better?

Nope.

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

SECTION [10]: Constructors


[10.1] 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.

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

[10.2] Is there any difference between List x; and List x();?

A big difference!

Suppose that List is the name of some class. Then function f() declares a
local List object called x:

void f()
{
List x; // Local object named x (of class List)
// ...
}

But function g() declares a function called x() that returns a List:

void g()
{
List x(); // Function named x (that returns a List)
// ...
}

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

[10.3] 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.

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

[10.4] Is the default constructor for Fred always Fred::Fred()?

No. A "default constructor" is a constructor that can be called with no arguments. Thus a constructor that takes no arguments is certainly a default constructor:

class Fred {
public:
Fred(); // Default constructor: can be called with no args
// ...
};

However it is possible (and even likely) that a default constructor can take arguments, provided they are given default values:

class Fred {
public:
Fred(int i=3, int j=5); // Default constructor: can be called with no args
// ...
};

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

[10.5] Which constructor gets called when I create an array of Fred objects?

Fred's default constructor[10.4] (except as discussed below).

There is no way to tell the compiler to call a different constructor (except as discussed below). If your class Fred doesn't have a default constructor[10.4], attempting to create an array of Fred objects is trapped as an error at compile
time.

class Fred {
public:
Fred(int i, int j);
// ... assume there is no default constructor[10.4] in class Fred ...
};

int main()
{
Fred a[10]; // ERROR: Fred doesn't have a default constructor
Fred* p = new Fred[10]; // ERROR: Fred doesn't have a default constructor
}

However if you are creating an STL[32.1] vector rather than an array of Fred (which you probably should be doing anyway since arrays are evil[21.5]), you don't have to have a default constructor in class Fred, since you can give
the vector a Fred object to be used to initialize the elements:

#include
using namespace std;

int main()
{
vector a(10, Fred(5,7));
// The 10 Fred objects in vector a will be initialized with Fred(5,7).
// ...
}

Even though you ought to use a vector rather than an array, there are times when an array might be the right thing to do, and for those, there is the "explicit initialization of arrays" syntax. Here's how it looks:

class Fred {
public:
Fred(int i, int j);
// ... assume there is no default constructor[10.4] in class Fred ...
};

int main()
{
Fred a[10] = {
Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7),
Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7)
};

// The 10 Fred objects in array a will be initialized with Fred(5,7).
// ...
}

Of course you don't have to do Fred(5,7) for every entry -- you can put in any numbers you want, even parameters or other variables. The point is that this syntax is (a) doable but (b) not as nice as the vector syntax. Remember this:
arrays are evil[21.5] -- unless there is a compelling reason to use an array,use a vector instead.

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

[10.6] Should my constructors use "initialization lists" or "assignment"?

Constructors should initialize all member objects in the initialization list.

For example, this constructor initializes member object x_ using an initialization list: Fred::Fred() : x_(whatever) { }. From a performance perspective, it is important to note that the whatever expression doesn't automatically cause a separate object to be created and copied into x_: if the types are the same the result of ...whatever... will be constructed directly inside x_.

In contrast the following constructor uses assignment:
Fred::Fred() { x_ = whatever; }. In this case the expression whatever causes a separate, temporary object to be created, and this temporary object is passed into the x_ object's assignment operator, then is destructed at the ;. That's inefficient.

There's another source of inefficiency as well: in the second (assignment) case, the object's default constructor (implicitly called before the constructor body's "{") might, for example, allocate some default amount of memory or open some default file. All this work could be for naught if the whatever expression and/or assignment operator causes the object to close that file and/or release that memory (e.g., if the default constructor didn't allocate a large enough pool of memory or if it opened the wrong file).

Conclusion: All other things being equal, your code will run faster if you use initialization lists rather than assignment.

============================================================================
[10.7] Should you use the this pointer in the constructor? [NEW!]

[Recently created with the help of Jim Hyslop (on 1/00).]

Some people feel you should not use the this pointer in a constructor because the this object is not fully formed yet. However you can use this in the constructor (in the {body} and even in the initialization list[10.6]) if you are careful.

Once you're in the {body} of the constructor, it's easy to imagine that you can use the this pointer since all the base class subobjects and the member objects will already have been fully constructed. However even there you must be careful. For example, if you call a virtual member function (or call some other function which turns around and calls a virtual member function) on the this object, you may not get what you want[23.1].

But you are even allowed to use the this pointer in the constructor's initializer list[10.6], provided you are very careful that you don't touch any member objects or base class subobjects that have not yet been constructed. This requires a rather intimate knowledge of the order that things happen in a constructor -- you have been warned. The safest thing to do is store the value of the this pointer somewhere and use that pointer later.

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

[10.8] What is the "Named Constructor Idiom"?

A technique that provides more intuitive and/or safer construction operations for users of your class.

The problem is that constructors always have the same name as the class.Therefore the only way to differentiate between the various constructors of a class is by the parameter list. But if there are lots of constructors, the differences between the constructors becomes somewhat subtle and error prone.

With the Named Constructor Idiom, you declare all the class's constructors in the private: or protected: sections, and you provide public static methods that return an object. These static methods are the so-called "Named Constructors."
In general there is one such static method for each different way to construct an object.

For example, suppose we are building a Point class that represents a position on the X-Y plane. Turns out there are two common ways to specify a 2-space coordinate: rectangular coordinates (X+Y), polar coordinates (Radius+Angle).
(Don't worry if you can't remember these; the point isn't the particulars of coordinate systems; the point is that there are several ways to create a Point object). Unfortunately the parameters for these two coordinate systems are the same: two floats. This would create an ambiguity error in the overloaded constructors:

class Point {
public:
Point(float x, float y); // Rectangular coordinates
Point(float r, float a); // Polar coordinates (radius and angle)
// ERROR: Overload is Ambiguous: Point::Point(float,float)
};

int main()
{
Point p = Point(5.7, 1.2); // Ambiguous: Which coordinate system?
}

One way to solve this ambiguity is to use the Named Constructor Idiom:

#include // To get sin() and cos()

class Point {
public:
static Point rectangular(float x, float y); // Rectangular coord's
static Point polar(float radius, float angle); // Polar coordinates
// These static methods are the so-called "named constructors"
// ...
private:
Point(float x, float y); // Rectangular coordinates
float x_, y_;
};

inline Point::Point(float x, float y)
: x_(x), y_(y) { }

inline Point Point::rectangular(float x, float y)
{ return Point(x, y); }

inline Point Point::polar(float radius, float angle)
{ return Point(radius*cos(angle), radius*sin(angle)); }

Now the users of Point have a clear and unambiguous syntax for creating Points in either coordinate system:

int main()
{
Point p1 = Point::rectangular(5.7, 1.2); // Obviously rectangular
Point p2 = Point::polar(5.7, 1.2); // Obviously polar
}

Make sure your constructors are in the protected: section if you expect Fred to have derived classes.

The Named Constructor Idiom can also be used to make sure your objects are always created via new[16.19].

============================================================================
[10.9] Why can't I initialize my static member data in my constructor's initialization list?

Because you must explicitly define your class's static data members.

Fred.h:

class Fred {
public:
Fred();
// ...
private:
int i_;
static int j_;
};

Fred.cpp (or Fred.C or whatever):

Fred::Fred()
: i_(10) // OK: you can (and should) initialize member data this way
j_(42) // Error: you cannot initialize static member data like this
{
// ...
}

// You must define static data members this way:
int Fred::j_ = 42;

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

[10.10] Why are classes with static data members getting linker errors?

Because static data members must be explicitly defined in exactly one compilation unit[10.9]. If you didn't do this, you'll probably get an "undefined external" linker error. For example:

// Fred.h

class Fred {
public:
// ...
private:
static int j_; // Declares static data member Fred::j_
// ...
};

The linker will holler at you ("Fred::j_ is not defined") unless you define (as opposed to merely declare) Fred::j_ in (exactly) one of your source files:

// Fred.cpp

#include "Fred.h"

int Fred::j_ = some_expression_evaluating_to_an_int;

// Alternatively, if you wish to use the implicit 0 value for static ints:
// int Fred::j_;

The usual place to define static data members of class Fred is file Fred.cpp (or Fred.C or whatever source file extension you use).

============================================================================
[10.11] What's the "static initialization order fiasco"?

A subtle way to kill your project.

The static initialization order fiasco is a very subtle and commonly misunderstood aspect of C++. Unfortunately it's very hard to detect – the errors occur before main() begins.

In short, suppose you have two static objects x and y which exist in separate source files, say x.cpp and y.cpp. Suppose further that the constructor for the y object calls some method on the x object.

That's it. It's that simple.

The tragedy is that you have a 50%-50% chance of dying. If the compilation unit for x.cpp happens to get initialized first, all is well. But if the compilation unit for y.cpp get initialized first, then y's constructor will get
run before x's constructor, and you're toast. I.e., y's constructor will call a method on the x object, yet the x object hasn't yet been constructed.
I hear they're hiring down at McDonalds. Enjoy your new job flipping burgers.
If you think it's "exciting" to play Russian Roulette with live rounds in half the chambers, you can stop reading here. On the other hand if you like to improve your chances of survival by preventing disasters in a systematic way,
you probably want to read the next FAQ[10.12].

Note: The static initialization order fiasco does not apply to builtin/intrinsic types like int or char*. For example if you create a static float object, there is never a problem with static initialization order. The only time the static initialization order is truly a fiasco is when your static or global objects have a constructor.

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

[10.12] How do I prevent the "static initialization order fiasco"?

Use the "construct on first use" idiom, which simply means to wrap your static object inside a function.

For example, suppose you have two classes, Fred and Barney. There is a global Fred object called x, and a global Barney object called y. Barney's constructor invokes the goBowling() method on the x object. The file x.cpp defines the x object:

// File x.cpp
#include "Fred.hpp"
Fred x;

The file y.cpp defines the y object:

// File y.cpp
#include "Barney.hpp"
Barney y;

For completeness the Barney constructor might look something like this:

// File Barney.cpp
#include "Barney.hpp"

Barney::Barney()
{
// ...
x.goBowling();
// ...
}

As described above[10.11], the disaster occurs if y is constructed before x, which happens 50% of the time since they're in different source files.

There are many solutions to this problem, but a very simple and completely portable solution is to replace the global Fred object, x, with a global function, x(), that returns the Fred object by reference.

// File x.cpp

#include "Fred.hpp"

Fred& x()
{
static Fred* ans = new Fred();
return *ans;
}

Since static local objects are constructed the first time control flows over their declaration (only), the above new Fred() statement will only happen once: the first time x() is called. Every subsequent call will return the same Fred object (the one pointed to by ans). Then all you do is change your usages of x
to x():

// File Barney.cpp
#include "Barney.hpp"

Barney::Barney()
{
// ...
x().goBowling();
// ...
}

This is called the Construct On First Use Idiom because it does just that: the global Fred object is constructed on its first use.

The downside of this approach is that the Fred object is never destructed. The C++ FAQ Book has a second technique that answers this concern (but at the cost of opening a "static de-initialization order fiasco").

Note: You don't have to do this for builtin/intrinsic types like int or char*. For example if you create a static or global float object, there is no need to wrap it within a function. The only time the static initialization order is truly a fiasco is when your static or global objects have a constructor.

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

[10.13] How do I prevent the "static initialization order fiasco" for my static data members?
Just use the same technique just described[10.12], but this time use a static member function rather than a global function.

Suppose you have a class X that has a static Fred object:

// File X.hpp

class X {
public:
// ...

private:
static Fred x_;
};

Naturally this static member is initialized separately:

// File X.cpp

#include "X.hpp"

Fred X::x_;

Naturally also the Fred object will be used in one or more of X's methods:

void X::someMethod()
{
x_.goBowling();
}

But now the "disaster scenario" is if someone somewhere somehow calls this method before the Fred object gets constructed. For example, if someone else creates a static X object and invokes its someMethod() method during static
initialization, then you're at the mercy of the compiler as to whether the compiler will construct X::x_ before or after the someMethod() is called. (Note that the ANSI/ISO C++ committee is working on this problem, but compilers
aren't yet generally available that handle these changes; watch this space for an update in the future.)

In any event, it's always portable and safe to change the X::x_ static data member into a static member function:

// File X.hpp

class X {
public:
// ...

private:
static Fred& x();
};

Naturally this static member is initialized separately:

// File X.cpp

#include "X.hpp"

Fred& X::x()
{
static Fred* ans = new Fred();
return *ans;
}

Then you simply change any usages of x_ to x():

void X::someMethod()
{
x().goBowling();
}

If you're super performance sensitive and you're concerned about the overhead of an extra function call on each invocation of X::someMethod() you can set up a static Fred& instead. As you recall, static local are only initialized once (the first time control flows over their declaration), so this will call X::x() only once: the first time X::someMethod() is called:

void X::someMethod()
{
static Fred& x = X::x();
x.goBowling();
}

Note: You don't have to do this for builtin/intrinsic types like int or char*. For example if you create a static or global float object, there is no need to wrap it within a function. The only time the static initialization order is truly a fiasco is when your static or global objects have a constructor.

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

[10.14] How can I handle a constructor that fails?

Throw an exception. See [17.1] for details.

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

SECTION [11]: Destructors


[11.1] 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., class Lock 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" member function. They are often abbreviated "dtor".

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

[11.2] What's the order that local objects are destructed?

In reverse order of construction: First constructed, last destructed.
In the following example, b's destructor will be executed first, then a's destructor:

void userCode()
{
Fred a;
Fred b;
// ...
}

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

[11.3] What's the order that objects in an array are destructed?

In reverse order of construction: First constructed, last destructed.
In the following example, the order for destructors will be a[9], a[8], ..., a[1], a[0]:
void userCode()
{
Fred a[10];
// ...
}

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

[11.4] Can I overload the destructor for my class?

No.

You can have only one destructor for a class Fred. It's always called Fred::~Fred(). It never takes any parameters, and it never returns anything.
You can't pass parameters to the destructor anyway, since you never explicitly
call a destructor[11.5] (well, almost never[11.10]).

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

[11.5] Should I explicitly call a destructor on a local variable?

No!

The destructor will get called again at the close } of the block in which the local was created. This is a guarantee of the language; it happens automagically; there's no way to stop it from happening. But you can get really bad results from calling a destructor on the same object a second time! Bang! You're dead!

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

[11.6] What if I want a local to "die" before the close } of the scope in which it was created? Can I call a destructor on a local if I really want to?

No! [For context, please read the previous FAQ[11.5]].

Suppose the (desirable) side effect of destructing a local File object is to close the File. Now suppose you have an object f of a class File and you want File f to be closed before the end of the scope (i.e., the }) of the scope of object f:

void someCode()
{
File f;

// ... [This code that should execute when f is still open] ...

// <-- We want the side-effect of f's destructor here!

// ... [This code that should execute after f is closed] ...
}

There is a simple solution to this problem[11.7]. But in the mean time,remember: Do not explicitly call the destructor![11.5]
==============================================================================

[11.7] OK, OK already; I won't explicitly call the destructor of a local; but how do I handle the above situation?

[For context, please read the previous FAQ[11.6]].

Simply wrap the extent of the lifetime of the local in an artificial block {
... }:

void someCode()
{
{
File f;
// ... [This code will execute when f is still open] ...
}
// ^-- f's destructor will automagically be called here!

// ... [This code will execute after f is closed] ...
}

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

[11.8] What if I can't wrap the local in an artificial block? [UPDATED!]

[Recently added the note about constructors at the end (on 3/00).]

Most of the time, you can limit the lifetime of a local by wrapping the local in an artificial block ({ ... })[11.7]. But if for some reason you can't do that, add a member function that has a similar effect as the destructor. But do not call the destructor itself!

For example, in the case of class File, you might add a close() method. Typically the destructor will simply call this close() method. Note that the close() method will need to mark the File object so a subsequent call won't re-close an already-closed File. E.g., it might set the fileHandle_ data member to some nonsensical value such as -1, and it might check at the beginning to see if the fileHandle_ is already equal to -1:

class File {
public:
void close();
~File();
// ...
private:
int fileHandle_; // fileHandle_ >= 0 if/only-if it's open
};

File::~File()
{
close();
}

void File::close()
{
if (fileHandle_ >= 0) {
// ... [Perform some operating-system call to close the file] ...
fileHandle_ = -1;
}
}

Note that the other File methods may also need to check if the fileHandle_ is -1 (i.e., check if the File is closed).

Note also that any constructors that don't actually open a file should set fileHandle_ to -1.

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

[11.9] But can I explicitly call a destructor if I've allocated my object with new?

Probably not.

Unless you used placement new[11.10], you should simply delete the object rather than explicitly calling the destructor. For example, suppose you allocated the object via a typical new expression:

Fred* p = new Fred();

Then the destructor Fred::~Fred() will automagically get called when you delete it via:

delete p; // Automagically calls p->~Fred()

You should not explicitly call the destructor, since doing so won't release the memory that was allocated for the Fred object itself. Remember: delete p does two things[16.8]: it calls the destructor and it deallocates the memory.

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

[11.10] What is "placement new" and why would I use it?

There are many uses of placement new. The simp lest use is to place an object at a particular location in memory. This is done by supplying the place as a pointer parameter to the new part of a new expression:

#include // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred

void someCode()
{
char memory[sizeof(Fred)]; // Line #1
void* place = memory; // Line #2

Fred* f = new(place) Fred(); // Line #3 (see "DANGER" below)
// The pointers f and place will be equal

// ...
}

Line #1 creates an array of sizeof(Fred) bytes of memory, which is big enough to hold a Fred object. Line #2 creates a pointer place that points to the first byte of this memory (experienced C programmers will note that this step was unnecessary; it's there only to make the code more obvious). Line #3 essentially just calls the constructor Fred::Fred(). The this pointer in the Fred constructor will be equal to place. The returned pointer f will therefore be equal to place.

ADVICE: Don't use this "placement new" syntax unless you have to. Use it only when you really care that an object is placed at a particular location in memory. For example, when your hardware has a memory-mapped I/O timer device, and you want to place a Clock object at that memory location.

DANGER: You are taking sole responsibility that the pointer you pass to the "placement new" operator points to a region of memory that is big enough and is properly aligned for the object type that you're creating. Neither the compiler nor the run-time system make any attempt to check whether you did this
right. If your Fred class needs to be aligned on a 4 byte boundary but you supplied a location that isn't properly aligned, you can have a serious disaster on your hands (if you don't know what "alignment" means, please don't use the placement new syntax). You have been warned.

You are also solely responsible for destructing the placed object. This is done by explicitly calling the destructor:

void someCode()
{
char memory[sizeof(Fred)];
void* p = memory;
Fred* f = new(p) Fred();
// ...
f->~Fred(); // Explicitly call the destructor for the placed object
}

This is about the only time you ever explicitly call a destructor.

============================================================================
[11.11] When I write a destructor, do I need to explicitly call the destructors for my member objects?

No. You never need to explicitly call a destructor (except with placement new[11.10]).

A class's destructor (whether or not you explicitly define one) automagically invokes the destructors for member objects. They are destroyed in the reverse order they appear within the declaration for the class.

class Member {
public:
~Member();
// ...
};

class Fred {
public:
~Fred();
// ...
private:
Member x_;
Member y_;
Member z_;
};

Fred::~Fred()
{
// Compiler automagically calls z_.~Member()
// Compiler automagically calls y_.~Member()
// Compiler automagically calls x_.~Member()
}

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

[11.12] When I write a derived class's destructor, do I need to explicitly call the destructor for my base class?

No. You never need to explicitly call a destructor (except with placement new[11.10]).

A derived class's destructor (whether or not you explicitly define one) automagically invokes the destructors for base class subobjects. Base classes are destructed after member objects. In the event of multiple inheritance, direct base classes are destructed in the reverse order of their appearance in the inheritance list.

class Member {
public:
~Member();
// ...
};

class Base {
public:
virtual ~Base(); // A virtual destructor[20.4]
// ...
};

class Derived : public Base {
public:
~Derived();
// ...
private:
Member x_;
};

Derived::~Derived()
{
// Compiler automagically calls x_.~Member()
// Compiler automagically calls Base::~Base()
}

Note: Order dependencies with virtual inheritance are trickier. If you are relying on order dependencies in a virtual inheritance hierarchy, you'll need a lot more information than is in this FAQ.

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

SECTION [12]: Assignment operators


[12.1] What is "self assignment"? [UPDATED!]

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.1]), 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 theassignment operator in the previous FAQ[12.2] to handle exceptions thrown by new[16.5] and/or exceptions thrown by the copy constructor[17.1] 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 add "if (this == &f) return *this;" to improve the efficiency of self assignment. This is generally the wrong tradeoff. If self assignment only occurs 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.

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 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? [UPDATED!]

[Recently got rid of #if/#else/#endif by splitting the example thanks to Stan Brown (on 1/00).]

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 (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 string-like class rather than an array of char in the first place[17.3] since arrays are evil[21.5].

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

[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 ).

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;
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.
============================================================================
[13.10] Should I design my classes from the outside (interfaces first) or from the inside (data first)?
[Recently added friend relationship between LinkedListIterator and LinkedList thanks to Mónica García García; reworded "In the case of OO software..." sentence thanks to Fabrice Clerc (on 3/00).]

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?

One man's answer: 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)
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 key insight is that the LinkedList class does not have any methods that lets users access the Nodes. Nodes are an implementation technique that is completely buried. The LinkedList class could have its internals replaced with a doubly linked list, or even an array, and the only difference would be some performance differences with the prepend(elem) and append(elem) methods.

#include // Poor man's exception handling

typedef int bool; // Someday we won't have to do this

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-listclass. 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[32.1] such as the list 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?

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 case s, 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.

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

[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.8]. 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 is neither inherited nor transitive"?

I may declare you as my friend, but that doesn't mean I necessarily trust either your kids or your friends.
* 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.

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

[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 and


[15.1] Why should I use instead of the traditional ?

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()):
* Better type safety: With , the type of object being I/O'd is known statically by the compiler. In contrast, uses "%" fields to figure out the types dynamically.
* Less error prone: With , 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++ 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()?!).
* Subclassable: The C++ mechanism is built from real classes such as ostream and istream. Unlike 's FILE*, these 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.

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

[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 cin:

#include

int main()
{
cout << "Enter numbers separated by whitespace (use -1 to quit): ";
int i = 0;
while (i != -1) {
cin >> i; // BAD FORM -- See comments below
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 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

int main()
{
cout << "Enter a number, or -1 to quit: ";
int i = 0;
while (cin >> i) { // GOOD FORM
if (i == -1) break;
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 (cin >> i) to while ((cin >> i) && (i != -1)), but that's not reallythe 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 (cin >> foo) syntax work?

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

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

To convert an istream into a boolean, the compiler calls a member function called 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 cin.operator void*(), just as if you had casted it explicitly such as (void*)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:
cin >> foo >> bar;
The operator>> is left-associative, which means the above is parsed as:

(cin >> foo) >> bar;

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

readFrom( readFrom(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, cin >> foo. This expression returns cin (more precisely, it returns a reference to its left-hand argument) to the next expression. The next expression also returns (a reference to) 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 (! cin.eof()) { // WRONG! (not reliable)
cin >> x;
++i;
// Work with x ...
}

What you really need is:

int i = 0;
while (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 (;;) {
cout << "Name: ";
cin >> name;
cout << "Age: ";
cin >> age;
}

What you really want is:

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

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

[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

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

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

int main()
{
Fred f;
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 << cout rather than 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] 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

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

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

int main()
{
Fred f;
cout << "Enter a Fred object: ";
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.8] 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 ostream& operator<< (ostream& o, const Base& b);
// ...
protected:
virtual void print(ostream& o) const;
};

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

class Derived : public Base {
protected:
virtual void print(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 print(ostream&) const. In particular, they do not provide their own operator<<.

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

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

[15.9] How can I "reopen" cin and 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 cin and cout. Suppose further that your operating system (such as DOS or OS/2) insists on translating "\r\n" into "\n" on input from cin, and "\n" to "\r\n" on output to cout or cerr.
Unfortunately there is no standard way to cause cin, cout, and/or 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.10] Why can't I open a file in a different directory such as "..\test.dat"?
[Recently added an explanation that the library routines treat "/" and "\" interchangeably thanks to Stan Brown (on 1/00).]

Because "\t" is a tab character.

You should use forward slashes in your filenames, even on an operating system that uses backslashes such as DOS, Windows, OS/2, etc. For example:

#include
#include

int main()
{
#if 1
ifstsream file("../test.dat"); // RIGHT!
#else
ifstsream 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; use "/version/next/alpha/beta/test.dat" instead, even on systems that use a "\" as the directory separator such as DOS, Windows, OS/2, etc. This is because the library routines on these operating systems handle "/" and
"\" interchangeably.

SECTION [16]: Freestore management


[16.1] Does delete p delete the pointer p, or the pointed-to-data *p?

The pointed-to-data.

The keyword should really be delete_the_thing_pointed_to_by. The same abuse of English occurs when freeing the memory pointed to by a pointer in C: free(p) really means free_the_stuff_pointed_to_by(p).

============================================================================
[16.2] Can I free() pointers allocated with new? Can I delete pointers allocated with malloc()?

No!

It is perfectly legal, moral, and wholesome to use malloc() and delete in the same program, or to use new and free() in the same program. But it is illegal, immoral, and despicable to call free() with a pointer allocated via new, or to call delete on a pointer allocated via malloc().

Beware! I occasionally get e-mail from people telling me that it works OK for them on machine X and compiler Y. That does not make it right! Sometimes people say, "But I'm just working with an array of char." Nonetheless do not mix malloc() and delete on the same pointer, or new and free() on the same
pointer! If you allocated v ia p = new char[n], you must use delete[] p; you must not use free(p). Or if you allocated via p = malloc(n), you must use free(p); you must not use delete[] p or delete p! Mixing these up could cause a catastrophic failure at runtime if the code was ported to a new machine, a new compiler, or even a new version of the same compiler.

============================================================================[16.3] 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 pointer 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.



[16.4] Can I use realloc() on pointers allocated via new?

No!

When realloc() has to copy the allocation, it uses a bitwise copy operation, which will tear many C++ objects to shreds. C++ objects should be allowed to copy themselves. They use their own copy constructor or assignment operator.
Besides all that, the heap that new uses may not be the same as the heap that malloc() and realloc() use!

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

[16.5] Do I need to check for NULL after p = new Fred()?

No! (But if you have an old compiler, you may have to force the compiler to have this behavior[16.6]).

It turns out to be a real pain to always write explicit NULL tests after every new allocation. Code like the following is very tedious:

Fred* p = new Fred();
if (p == NULL)
throw bad_alloc();

If your compiler doesn't support (or if you refuse to use) exceptions[17], your code might be even more tedious:

Fred* p = new Fred();
if (p == NULL) {
cerr << "Couldn't allocate memory for a Fred" << endl;
abort();
}

Take heart. In C++, if the runtime system cannot allocate sizeof(Fred) bytes of memory during p = new Fred(), a bad_alloc exception will be thrown. Unlike malloc(), new never returns NULL!

Therefore you should simply write:

Fred* p = new Fred(); // No need to check if p is NULL

However, if your compiler is old, it may not yet support this. Find out by checking your compiler's documentation under "new". If you have an old compiler, you may have to force the compiler to have this behavior[16.6].

============================================================================
[16.6] How can I convince my (older) compiler to automatically check new to see if it returns NULL?

Eventually your compiler will.

If you have an old compiler that doesn't auto magically perform the NULL test[16.5], you can force the runtime system to do the test by installing a "new handler" function. Your "new handler" function can do anything you want, such as print a message and abort() the program, delete some objects and return
(in which case operator new will retry the allocation), throw an exception, etc.

Here's a sample "new handler" that prints a message and calls abort(). The handler is installed using set_new_handler():

#include // To get set_new_handler
#include // To get abort()
#include // To get cerr

void myNewHandler()
{
// This is your own handler. It can do anything you want.
cerr << "Attempt to allocate memory failed!" << endl;
abort();
}

int main()
{
set_new_handler(myNewHandler); // Install your "new handler"
// ...
}

After the set_new_handler() line is executed, operator new will call your myNewHandler() if/when it runs out of memory. This means that new will never return NULL:

Fred* p = new Fred(); // No need to check if p is NULL

Note: Please use this abort() approach as a last resort. If your compiler supports exception handling[17], please consider throwing an exception instead of calling abort().

Note: If some global/static object's constructor uses new, it won't use the myNewHandler() function since that constructor will get called before main() begins. Unfortunately there's no convenient way to guarantee that the set_new_handler() will be called before the first use of new. For example, even if you put the set_new_handler() call in the constructor of a global object, you still don't know if the module ("compilation unit") that contains that global object will be elaborated first or last or somewhere inbetween.
Therefore you still don't have any guarantee that your call of set_new_handler() will happen before any other global's constructor gets invoked.

============================================================================
[16.7] Do I need to check for NULL before delete p?

No!

The C++ language guarantees that delete p will do nothing if p is equal to NULL. Since you might get the test backwards, and since most testing methodologies force you to explicitly test every branch point, you should not put in the redundant if test.

Wrong:

if (p != NULL)
delete p;

Right:

delete p;

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

[16.8] What are the two steps that happen when I say delete p?

delete p is a two-step process: it calls the destructor, then releases the memory. The code generated for delete p looks something like this (assuming p is of type Fred*):

// Original code: delete p;
if (p != NULL) {
p->~Fred();
operator delete(p);
}

The statement p->~Fred() calls the destructor for the Fred object pointed to by
p.

The statement operator delete(p) calls the memory deallocation primitive, void operator delete(void* p). This primitive is similar in spirit to free(void* p). (Note, however, that these two are not interchangeable; e.g., there is no guarantee that the two memory deallocation primitives even use the same heap!).

============================================================================
[16.9] In p = new Fred(), does the Fred memory "leak" if the Fred constructor throws an exception?

No.

If an exception occurs during the Fred constructor of p = new Fred(), the C++ language guarantees that the memory sizeof(Fred) bytes that were allocated will automagically be released back to the heap.

Here are the details: new Fred() is a two-step process:

1. sizeof(Fred) bytes of memory are allocated using the primitive void* operator new(size_t nbytes). This primitive is similar in spirit to malloc(size_t nbytes). (Note, however, that these two are not interchangeable; e.g., there is no guarantee that the two memory allocation primitives even use the same heap!).

2. It constructs an object in that memory by calling the Fred constructor. The pointer returned from the first step is passed as the this parameter to the constructor. This step is wrapped in a try ... catch block to handle the case when an exception is thrown during this step.

Thus the actual generated code looks something like:

// Original code: Fred* p = new Fred();
Fred* p = (Fred*) operator new(sizeof(Fred));
try {
new(p) Fred(); // Placement new[11.10]
} catch (...) {
operator delete(p); // Deallocate the memory
throw; // Re-throw the exception
}

The statement marked "Placement new[11.10]" calls the Fred constructor. The
pointer p becomes the this pointer inside the constructor, Fred::Fred().

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

[16.10] How do I allocate / unallocate an array of things?

Use p = new T[n] and delete[] p:

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

Any time you allocate an array of objects via new (usually with the [n] 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).

============================================================================
[16.11] What if I forget the [] when deleteing array allocated via new T[n]?

All life comes to a catastrophic end.

It is the programmer's --not the compiler's-- responsibility to get the connection between new T[n] and delete[] p 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.

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

[16.12] Can I drop the [] when deleteing array of some built-in type (char, int, etc)?

No!

Sometimes programmers think that the [] in the delete[] p only exists so the compiler will call the appropriate destructors for all elements in the array. Because of this reasoning, they assume that an array of some built-in type such as char or int can be deleted without the []. E.g., they assume the following
is valid code:

void userCode(int n)
{
char* p = new char[n];
// ...
delete p; // <-- ERROR! Should be delete[] p !
}

But the above code is wrong, and it can cause a disaster at runtime. In particular, the code that's called for delete p is operator delete(void*), but the code that's called for delete[] p is operator delete[](void*). The default behavior for the latter is to call the former, but users are allowed to replace the latter with a different behavior (in which case they would normally also replace the corresponding new code in operator new[](size_t)). If they replaced the delete[] code so it wasn't compatible with the delete code, and
you called the wrong one (i.e., if you said delete p rather than delete[] p), you could end up with a disaster at runtime.

============================================================================
[16.13] After p = new Fred[n], how does the compiler know there are n objects to be destructed during delete[] p?

Short answer: Magic.

Long answer: The run-time system stores the number of objects, n, somewhere where it can be retrieved if you only know the pointer, p. There are two popluar techniques that do this. Both these techniques are in use by commercial grade compilers, both have tradeoffs, and neither is perfect. These techniques are:
* Over-allocate the array and put n just to the left of the first Fred object[33.6].
* Use an associative array with p as the key and n as the value[33.7].

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

[16.14] Is it legal (and moral) for a member function to say delete this?

As long as you're careful, it's OK for an object to commit suicide (delete
this).

Here's how I define "careful":

1. You must be absolutely 100% positive sure that this object was allocated via new (not by new[], nor by placement new[11.10], nor a local object on the stack, nor a global, nor a member of another object; but by plain ordinary new).

2. You must be absolutely 100% positive sure that your member function will be the last member function invoked on this object.

3. You must be absolutely 100% positive sure that the rest of your member function (after the delete this line) doesn't touch any piece of this object (including calling any other member functions or touching any data members).

4. You must be absolutely 100% positive sure that no one even touches the this pointer itself after the delete this line. In other words, you must not examine it, compare it with another pointer, compare it with NULL, print it, cast it, do anything with it.

Naturally the usual caveats apply in cases where your this pointer is a pointer to a base class when you don't have a virtual destructor[20.4].

============================================================================
[16.15] How do I allocate multidimensional arrays using new?

There are many ways to do this, depending on how flexible you want the array sizing to be. On one extreme, if you know all the dimensions at compile-time, you can allocate multidimensional arrays statically (as in C):

class Fred { /*...*/ };
void someFunction(Fred& fred);

void manipulateArray()
{
const unsigned nrows = 10; // Num rows is a compile-time constant
const unsigned ncols = 20; // Num columns is a compile-time constant
Fred matrix[nrows][ncols];

for (unsigned i = 0; i < nrows; ++i) {
for (unsigned j = 0; j < ncols; ++j) {
// Here's the way you access the (i,j) element:
someFunction( matrix[i][j] );

// You can safely "return" without any special delete code:
if (today == "Tuesday" && moon.isFull())
return; // Quit early on Tuesdays when the moon is full
}
}

// No explicit delete code at the end of the function either
}

More commonly, the size of the matrix isn't known until run-time but you know that it will be rectangular. In this case you need to use the heap ("freestore"), but at least you are able to allocate all the elements in one freestore chunk.

void manipulateArray(unsigned nrows, unsigned ncols)
{
Fred* matrix = new Fred[nrows * ncols];

// Since we used a simple pointer above, we need to be VERY
// careful to avoid skipping over the delete code.
// That's why we catch all exceptions:
try {

// Here's how to access the (i,j) element:
for (unsigned i = 0; i < nrows; ++i) {
for (unsigned j = 0; j < ncols; ++j) {
someFunction( matrix[i*ncols + j] );
}
}

// If you want to quit early on Tuesdays when the moon is full,
// make sure to do the delete along ALL return paths:
if (today == "Tuesday" && moon.isFull()) {
delete[] matrix;
return;
}

// ...

}
catch (...) {
// Make sure to do the delete when an exception is thrown:
delete[] matrix;
throw; // Re-throw the current exception
}

// Make sure to do the delete at the end of the function too:
delete[] matrix;
}

Finally at the other extreme, you may not even be guaranteed that the matrix is rectangular. For example, if each row could have a different length, you'll need to allocate each row individually. In the following function, ncols[i] is the number of columns in row number i, where i varies between 0 and nrows-1
inclusive.

void manipulateArray(unsigned nrows, unsigned ncols[])
{
Fred** matrix = new Fred*[nrows];
for (unsigned i = 0; i < nrows; ++i)
matrix[i] = new Fred[ ncols[i] ];

// Since we used a simple pointer above, we need to be VERY
// careful to avoid skipping over the delete code.
// That's why we catch all exceptions:
try {

// Here's how to access the (i,j) element:
for (unsigned i = 0; i < nrows; ++i) {
for (unsigned j = 0; j < ncols[i]; ++j) {
someFunction( matrix[i][j] );
}
}

// If you want to quit early on Tuesdays when the moon is full,
// make sure to do the delete along ALL return paths:
if (today == "Tuesday" && moon.isFull()) {
for (unsigned i = nrows; i > 0; --i)
delete[] matrix[i-1];
delete[] matrix;
return;
}

// ...

}
catch (...) {
// Make sure to do the delete when an exception is thrown:
for (unsigned i = nrows; i > 0; --i)
delete[] matrix[i-1];
delete[] matrix;
throw; // Re-throw the current exception
}

// Make sure to do the delete at the end of the function too.
// Note that deletion is the opposite order of allocation:
for (i = nrows; i > 0; --i)
delete[] matrix[i-1];
delete[] matrix;
}

Note the funny use of matrix[i-1] in the deletion process. This prevents wrap-around of the unsigned value when i goes one step below zero.

Finally, note that pointers and arrays are evil[21.5]. It is normally much better to encapsulate your pointers in a class that has a safe and simple interface. The following FAQ[16.16] shows how to do this.

============================================================================
[16.16] But the previous FAQ's code is SOOOO tricky and error prone! Isn't there a simpler way?

Yep.

The reason the code in the previous FAQ[16.15] was so tricky and error prone was that it used pointers, and we know that pointers and arrays are evil[21.5]. The solution is to encapsulate your pointers in a class that has a safe and simple interface. For example, we can define a Matrix class that handles a rectangular matrix so our user code will be vastly simplified when compared to the the rectangular matrix code from the previous FAQ[16.15]:

// The code for class Matrix is shown below...
void someFunction(Fred& fred);

void manipulateArray(unsigned nrows, unsigned ncols)
{
Matrix matrix(nrows, ncols); // Construct a Matrix called matrix

for (unsigned i = 0; i < nrows; ++i) {
for (unsigned j = 0; j < ncols; ++j) {
// Here's the way you access the (i,j) element:
someFunction( matrix(i,j) );

// You can safely "return" without any special delete code:
if (today == "Tuesday" && moon.isFull())
return; // Quit early on Tuesdays when the moon is full
}
}

// No explicit delete code at the end of the function either
}

The main thing to notice is the lack of clean-up code. For example, there aren't any delete statements in the above code, yet there will be no memory leaks, assuming only that the Matrix destructor does its job correctly.

Here's the Matrix code that makes the above possible:

class Matrix {
public:
Matrix(unsigned nrows, unsigned ncols);
// Throws a BadSize object if either size is zero
class BadSize { };

// Based on the Law Of The Big Three[25.9]:
~Matrix();
Matrix(const Matrix& m);
Matrix& operator= (const Matrix& m);

// Access methods to get the (i,j) element:
Fred& operator() (unsigned i, unsigned j);
const Fred& operator() (unsigned i, unsigned j) const;
// These throw a BoundsViolation object if i or j is too big
class BoundsViolation { };

private:
Fred* data_;
unsigned nrows_, ncols_;
};

inline Fred& Matrix::operator() (unsigned row, unsigned col)
{
if (row >= nrows_ || col >= ncols_) throw BoundsViolation();
return data_[row*ncols_ + col];
}

inline const Fred& Matrix::operator() (unsigned row, unsigned col) const
{
if (row >= nrows_ || col >= ncols_) throw BoundsViolation();
return data_[row*ncols_ + col];
}

Matrix::Matrix(unsigned nrows, unsigned ncols)
: data_ (new Fred[nrows * ncols]),
nrows_ (nrows),
ncols_ (ncols)
{
if (nrows == 0 || ncols == 0)
throw BadSize();
}

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

Note that the above Matrix class accomplishes two things: it moves some tricky memory management code from the user code (e.g., main()) to the class, and it reduces the overall bulk of program (e.g., assuming Matrix is even mildly reusable, moving complexity from the users of Matrix into Matrix itself is equivalent to moving complexity from the many to the few). And anyone who's seen Star Trek 3 knows that the good of the many outweighs the good of the few... or the one.

============================================================================
[16.17] But the above Matrix class is specific to Fred! Isn't there a way to make it generic?

Yep; just use templates[31]:

template // See section on templates[31] for more
class Matrix {
public:
Matrix(unsigned nrows, unsigned ncols);
// Throws a BadSize object if either size is zero
class BadSize { };

// Based on the Law Of The Big Three[25.9]:
~Matrix();
Matrix(const Matrix& m);
Matrix& operator= (const Matrix& m);

// Access methods to get the (i,j) element:
T& operator() (unsigned i, unsigned j);
const T& operator() (unsigned i, unsigned j) const;
// These throw a BoundsViolation object if i or j is