FAQ 16.08 What is the named constructor idiom?

An idiom that allows a specific name for an operation that is similar to a constructor.

Occasionally, classes have a large suite of overloaded constructors. Because all constructors for a class have the same name, it can be confusing to select between the various overloaded constructors. When this happens, the named constructor idiom may be appropriate.

For example, consider a complex number class, Complex, that supports construction using either polar coordinates (magnitude, angle) or rectangular coordinates (real part, imaginary part). Unfortunately, these constructors are very similar; both constructors take two floats. Should Complex(2,1) be interpreted as specifying polar form ("2 at angle 1") or as specifying rectangular form ("2 plus 1 times the imaginary constant")?

Many potential solutions exist to resolve this ambiguity. A boolean flag could indicate which is intended, or an extra dummy parameter on one of the constructors could be used to avoid runtime overhead by making the selection at compile time rather than at runtime. Another solution is to use the named constructor idiom, which is a way of using static member functions to provide alternative constructors for a class. Usually, the named constructor idiom results in user code that is more direct and readable:

 #include <cmath> #include <iostream> using namespace std; class Complex { public:   Complex(float real=0.0) throw();   static Complex rect(float real, float imag) throw();   <-- 1   static Complex polar(float mag,  float ang) throw();   <-- 1 private:   Complex(float real, float imag) throw();   float real_, imag_; }; inline Complex::Complex(float real) throw() : real_(real) , imag_(0) { } inline Complex::Complex(float real, float imag) throw() : real_(real) , imag_(imag) { } inline Complex Complex::rect(float real, float imag) throw() { return Complex(real, imag); } inline Complex Complex::polar(float mag,  float ang) throw() { return Complex(mag*cos(ang), mag*sin(ang)); } 

(1) The so-called named constructors

Both rect() and polar() are static member functions that operate like constructors. Users explicitly call whichever version they want.

 int main() {   Complex a;                                         <-- 1   Complex b = 3.14;                                  <-- 2   Complex c = Complex::rect(3,2);                    <-- 3   Complex d = Complex::polar(3,2);                   <-- 4 } 

(1) real part=0, imag part=0

(2) real part=3.14, imag part=0

(3) real part=3, imag part=2

(4) magnitude=3, angle=2 radians



C++ FAQs
C Programming FAQs: Frequently Asked Questions
ISBN: 0201845199
EAN: 2147483647
Year: 2005
Pages: 566
Authors: Steve Summit

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net