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.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
A big difference!
Suppose that List is the name of some class. Then function
But function
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Nope.
Let's work an example. Suppose you want your constructor
Some people do it anyway. Unfortunately it doesn't do what they want. For
example, the line
You can sometimes combine two constructors is via a default parameter:
If that doesn't work, e.g., if there isn't an appropriate default parameter
that combines the two constructors, sometimes you can share their common code
in a private
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
No. A "default constructor" is a constructor that can be called with no arguments. One example of this is a constructor that takes no parameters:
Another example of a "default constructor" is one that can take arguments, provided they are given default values:
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Fred's default constructor (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, attempting to create an array of Fred objects is trapped as an error at compile time.
However if you are constructing an object of the standard
Even though you ought to use a
Of course you don't have to do
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Initialization lists. In fact, constructors should initialize all member objects in the initialization list.
For example, this constructor initializes member object x_ using an
initialization list:
The other (inefficient) way to build constructors is via assignment, such as:
As if that wasn't bad enough, there's another source of inefficiency when using assignment in a constructor: the member object will get fully constructed by its default constructor, and this 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.
Note: There is no performance difference if the type of x_ is some
built-in/intrinsic type, such as int or
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Some people feel you should not use the this pointer in a constructor
because the object is not fully formed yet. However you can use this
in the constructor (in the
Here is something that always works: the
Here is something that never works: the
Here is something that sometimes works: if you pass any of the data members in this object to another data member's initializer, you must make sure that the other data member has already been initialized. The good news is that you can determine whether the other data member has (or has not) been initialized using some straightforward language rules that are independent of the particular compiler you're using. The bad news it that you have to know those language rules (e.g., base class sub-objects are initialized first (look up the order if you have multiple and/or virtual inheritance!), then data members defined in the class are initialized in the order in which they appear in the class declaration). If you don't know these rules, then don't pass any data member from the this object (regardless of whether or not you explicitly use the this keyword) to any other data member's initializer! And if you do know the rules, please be careful.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
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 them become 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:
One way to solve this ambiguity is to use the Named Constructor Idiom:
Now the users of Point have a clear and unambiguous syntax for creating Points in either coordinate system:
Make sure your constructors are in the protected section if you expect Point to have derived classes.
The Named Constructor Idiom can also be used to make sure your objects are always created via new.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Because you must explicitly define your class's static data members.
Fred.h:
Fred.cpp (or Fred.C or whatever):
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Because static data members must be
explicitly defined in exactly one compilation unit. If you didn't do
this, you'll probably get an
The linker will holler at you (
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).
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
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
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 initialization for the y object (typically the y object's constructor) 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 initialization will get run before x's initialization, and you're toast. E.g., y's constructor could 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.
Note: The static initialization order fiasco can also, in some cases, apply to built-in/intrinsic types.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
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
The file y.cpp defines the y object:
For completeness the Barney constructor might look something like this:
As described above, 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,
Since static local objects are constructed the first time control flows over
their declaration (only), the above
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. There is another technique that answers this concern, but it needs to be used with care since it creates the possibility of another (equally nasty) problem.
Note: The static initialization order fiasco can also, in some cases, apply to built-in/intrinsic types.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Short answer: it's possible to use a static object rather than a static pointer, but doing so opens up another (equally subtle, equally nasty) problem.
Long answer: sometimes people worry about the fact that the previous solution "leaks." In many cases, this is not a problem, but it is a problem in some cases. Note: even though the object pointed to by ans in the previous FAQ is never deleted, the memory doesn't actually "leak" when the program exits since the operating system automatically reclaims all the memory in a program's heap when that program exits. In other words, the only time you'd need to worry about this is when the destructor for the Fred object performs some important action (such as writing something to a file) that must occur sometime while the program is exiting.
In those cases where the construct-on-first-use object (the Fred, in
this case) needs to eventually get destructed, you might consider changing
function
However there is (or rather, may be) a rather subtle problem with this change. To understand this potential problem, let's remember why we're doing all this in the first place: we need to make 100% sure our static object (a) gets constructed prior to its first use and (b) doesn't get destructed until after its last use. Obviously it would be a disaster if any static object got used either before construction or after destruction. The message here is that you need to worry about two situations (static initialization and static deinitialization), not just one.
By changing the declaration from
The point is simple: if there are any other static objects whose destructors might use ans after ans is destructed, bang, you're dead. If the constructors of a, b and c use ans, you should normally be okay since the runtime system will, during static deinitialization, destruct ans after the last of those three objects is destructed. However if a and/or b and/or c fail to use ans in their constructors and/or if any code anywhere gets the address of ans and hands it to some other static object, all bets are off and you have to be very, very careful.
There is a third approach that handles both the static initialization and static deinitialization situations, but it has other non-trivial costs. I'm too lazy (and busy!) to write any more FAQs today so if you're interested in that third approach, you'll have to buy a book that describes that third approach in detail. The C++ FAQs book is one of those books, and it also gives the cost/benefit analysis to decide if/when that third approach should be used.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Just use the same technique just described, 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:
Naturally this static member is initialized separately:
Naturally also the Fred object will be used in one or more of X's methods:
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
In any event, it's always portable and safe to change the
Naturally this static member is initialized separately:
Then you simply change any usages of x_ to
If you're super performance sensitive and you're concerned about the overhead
of an extra function call on each invocation of
Note: The static initialization order fiasco can also, in some cases, apply to built-in/intrinsic types.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Yes.
If you initialize your built-in/intrinsic type using a function call, the static initialization order fiasco is able to kill you just as bad as with user-defined/class types. For example, the following code shows the failure:
The output of this little program will show that it uses y before initializing it. The solution, as before, is the Construct On First Use Idiom:
Of course you might be able to simplify this by moving the initialization code for x and y into their respective functions:
And, if you can get rid of the print statements you can further simplify these to something really simple:
Furthermore, since y is initialized using a constant expression, it no longer needs its wrapper function it can be a simple variable again.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Throw an exception. See [17.2] for details.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
It's a fairly useful way to exploit method chaining.
The fundamental problem solved by the Named Parameter Idiom is that C++ only supports positional parameters. For example, a caller of a function isn't allowed to say, "Here's the value for formal parameter xyz, and this other thing is the value for formal parameter pqr." All you can do in C++ (and C and Java) is say, "Here's the first parameter, here's the second parameter, etc." The alternative, called named parameters and implemented in the language Ada, is especially useful if a function takes a large number of mostly default-able parameters.
Over the years people have cooked up lots of workarounds for the lack of named
parameters in C and C++. One of these involves burying the parameter values
in a string parameter then parsing this string at run-time. This is what's
done in the second parameter of
The idea, called the Named Parameter Idiom, is to change the function's
parameters to methods of a newly created class, where all these methods return
We'll work an example to make the previous paragraph easier to understand.
The example will be for the "open a file" concept. Let's say that concept logically requires a parameter for the file's name, and optionally allows parameters for whether the file should be opened read-only vs. read-write vs. write-only, whether or not the file should be created if it doesn't already exist, whether the writing location should be at the end ("append") or the beginning ("overwrite"), the block-size if the file is to be created, whether the I/O is buffered or non-buffered, the buffer-size, whether it is to be shared vs. exclusive access, and probably a few others. If we implemented this concept using a normal function with positional parameters, the caller code would be very difficult to read: there'd be as many as 8 positional parameters, and the caller would probably make a lot of mistakes. So instead we use the Named Parameter Idiom.
Before we go through the implementation, here's what the caller code might look like, assuming you are willing to accept all the function's default parameters:
That's the easy case. Now here's what it might look like if you want to change a bunch of the parameters.
Notice how the "parameters", if it's fair to call them that, are in random order (they're not positional) and they all have names. So the programmer doesn't have to remember the order of the parameters, and the names are (hopefully) obvious.
So here's how to implement it: first we create a new class (OpenFile)
that houses all the parameter values as private data members. Then all the
methods (
The only other thing to do is make the constructor for class File to take an OpenFile object:
Note that OpenFile declares File as its friend, that way OpenFile
doesn't need a bunch of (otherwise useless)
Since each member function in the chain returns a reference, there is no copying of objects and the chain is highly efficient. Furthermore, if the various member functions are inline, the generated object code will probably be on par with C-style code that sets various members of a struct. Of course if the member functions are not inline, there may be a slight increase in code size and a slight decrease in performance (but only if the construction occurs on the critical path of a CPU-bound program; this is a can of worms I'll try to avoid opening; read the C++ FAQs book for a rather thorough discussion of the issues), so it may, in this case, be a tradeoff for making the code more reliable.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
E-mail the author
[ C++ FAQ Lite
| Table of contents
| Subject index
| About the author
| ©
| Download your own copy ]
Revised May 2, 2003