2012年2月15日 星期三

Constructor Initialization List


Constructor Initialization List

C++ has a special syntax used to initialize class data members in the constructor function. Initializing values may be placed in a comma-separated list after the constructor argument list and before the function body. A colon precedes the list of initializers. For example:

Example 4-11 - Constructor with Initialization List

1      // File: ex4-11.cpp
2     
3      #include <iostream>
4      using namespace std;
5     
6      class xyz
7      {
8        private:
9          int a, b, c;
10        public:
11          xyz() : a(1), b(2), c(3) { }            // default constructor
12          xyz(int, const xyz&);               // constructor #2 prototype
13          void print(void) { cout << a << b << c << endl; }
14      };
15     
16     
17      xyz::xyz(int aa, const xyz& hey) : a(aa), b(5), c(hey.c) {}
18     
19     
20      int main(void)
21      {
22        xyz yo;                        // uses default constructor
23     
24        xyz yoyo(2,yo);                     // uses constructor #2
25     
26        yo.print();
27     
28        yoyo.print();
29     
30        return 0;
31      }


******  Output  ******

123
253

There are three situations where constructor initialization lists are required:

•when a class contains a const data member
•when a class contains a reference data member
•when you wish to make reference to a specific, not-default constructor (this is especially useful with inheritance and containment)

The following example show initialization of a class with const and reference data members:

Example

class xyz
{
  private: 
    int a;
    const int b;
    int& c;
  public:
    xyz(int,int&);
     .
     .
     .
};
 
xyz::xyz(int i, int& j) : b(i+1), c(j)
{
  a = 0;
}
     .
     .
     .

int main(void)
{
  int z = 3,
      q = 5;
  xyz hey(z,q);
     .
     .
     .

After hey is declared, what are the values assigned to hey's a,  b, and c?

Example 4-11a – Another example using constructor initializers

1      #include <string>
2     
3      class tail
4      {
5          unsigned short length;
6      public:
7          tail(unsigned short len = 6);
8      };
9     
10      tail::tail(unsigned short len)
11      : length(len)
12      {}
13     
14     
15      class dog
16      {
17          tail tail_;
18          std::string    name_;
19      public:
20          dog(std::string name);
21      };
22     
23      dog::dog(std::string name)
24      : tail_(tail()), name_(name)
25      {}
26     
27      int main()
28      {
29          dog beagle("Emily");
30          return 0;
31      }


Notes:

Line 7

Line 10

Line 11

Line 18

Line 20

Line 24 – What if you do not include tail_(tail(), here?

Line 29

The following example illustrates some initialization lists. This example also shows how multiple constructors may be very applicable to a real-world situation. If you are not into algebra and geometry, skip the arithmetic.

Example 4-12  - The Point and Line classes.

1      // File: ex4-12p.h – Point class header file
2     
3      #ifndef POINT_H
4      #define POINT_H
5     
6      inline double square(double d) { return d*d; }
7     
8      class Line;        // forward declaration
9     
10      class Point
11      {
12      private:
13          double x;
14          double y;
15      public:
16     
17          // Constructors
18     
19          // Create Point at origin
20          Point(void);
21     
22          // Create Point using x-y coordinates
23          Point(double x1,double y1);
24     
25          // Create Point as midpoint of two Points
26          Point(const Point& p, const Point& q);
27     
28          // Create Point as intersection of two lines
29          Point(const Line& l,const Line &m);
30     
31          // Copy constructor
32          Point(const Point& p);
33     
34          // print a point as (x,y)
35          void print(void) const;
36     
37          // accessor functions
38          double get_x(void) const;
39          double get_y(void) const;
40     
41          // assign value to x member
42          void set_x(double x1);
43     
44          // assign value to y member
45          void set_y(double y1);
46     
47          // determine the distance to another point
48          double distance_to_Point(const Point& p) const;
49      };
50     
51      #endif


1      // File: ex4-12p.cpp – Point class source file
2     
3      #include <cmath>
4      #include <iostream>
5      using namespace std;
6     
7      #include "ex4-12p.h"
8      #include "ex4-12l.h"
9     
10      Point::Point(void)
11      {
12          x = 0.0; y = 0.0;
13      }
14     
15     
16      Point::Point(double x1,double y1)
17      {
18          x = x1; y = y1;
19      }
20     
21     
22      Point::Point(const Point& p)
23      {
24          x= p.x; y = p.y;
25      }
26     
27     
28      Point::Point(const Point& p, const Point& q)
29      {
30          x = (p.x+q.x)/2.; y = (p.y+q.y)/2.;
31      }
32     
33     
34      Point::Point(const Line& l,const Line &m)
35      {
36          if (l.slope() == m.slope())   // parallel or coincident Lines
37          {
38              x = HUGE_VAL;
39              y = HUGE_VAL;
40          }
41          else
42          {
43              x = (m.get_b()*l.get_c()-m.get_c()*l.get_b())/
44                  (l.get_b()*m.get_a()-m.get_b()*l.get_a());
45              y = (l.get_a()*m.get_c()-m.get_a()*l.get_c())/
46                  (l.get_b()*m.get_a()-m.get_b()*l.get_a());
47          }
48      }
49     
50     
51      void Point::print(void) const
52      {
53          cout << '(' << x << ',' << y << ')';
54      }
55     
56     
57      void Point::set_x(double x1)
58      {
59          x = x1;
60      }
61     
62     
63      void Point::set_y(double y1)
64      {
65          y = y1;
66      }
67     
68     
69      double Point::get_x(void) const
70      {
71          return x;
72      }
73     
74     
75      double Point::get_y(void) const
76      {
77          return y;
78      }
79     
80      double Point::distance_to_Point(const Point& p) const
81      {
82          return sqrt(square(p.x-x)+square(p.y-y));
83      }


1      // File: ex4-12l.cpp – Line class source file
2     
3      #include <cmath>
4      #include <cstring>
5      #include <iostream>
6      using namespace std;
7     
8      #include "ex4-12l.h"
9     
10      Line::Line(const Point& pp1,const Point& pp2) : p1(pp1), p2(pp2)
11      {
12          if (slope() == HUGE_VAL)
13          {
14              a = 1.0;
15              b = 0.0;
16              c = -pp1.get_x();
17          }
18          else
19          {
20              a = -slope();
21              b = 1.0;
22              c = slope()*pp1.get_x()-pp1.get_y();
23          }
24      }
25     
26     
27      // create a Line using equation coefficients
28      Line::Line(double c1, double c2, double c3)
29      : a(c1), b(c2), c(c3)
30      {
31          if (c1 != 0.0) p1 = Point(-c3/c1,0.0);
32          else if (c2 != 0.0) p1 = Point(1.0,-c3/c2);
33          else p1 = Point(0.0,0.0);
34          if (c2 != 0.0) p2 = Point(0.0,-c3/c2);
35          else if (c1 != 0.0) p2 = Point(-c3/c1,1.0);
36          else p2 = Point(0.0,0.0);
37      }
38     
39     
40      // create a Line through a Point parallel or perpendicular to a Line
41      Line::Line(const Point& p,const Line& l, const char* Line_type) : p1(p)
42      {
43          double m;      // slope
44          if (strcmp(Line_type,"parallel")==0.0) m = l.slope();
45          else if (l.slope() == 0.0) m = HUGE_VAL;
46          else if (l.slope() == HUGE_VAL) m = 0.0;
47          else m = -1./l.slope();
48          if (m == HUGE_VAL) {
49              a = 1.0;
50              b = 0.0;
51              c = -p.get_x();
52              p2.set_x(p1.get_x());
53              p2.set_y(p1.get_y()+1.0);
54          }
55          else {
56              a = m;
57              b = -1.0;
58              c = -m*p.get_x()+p.get_y();
59              p2.set_x(0.0);
60              p2.set_y(c);
61          }
62      }
63     
64     
65      // create a vertical/horizontal Line through a Point
66      Line::Line(const Point& p, const char* Line_type) : p1(p)
67      {
68          if (strcmp(Line_type,"vertical") == 0)
69          {
70              p2.set_x(p1.get_x());
71              p2.set_y(p1.get_y()+1);
72              a = 1.0;
73              b = 0.0;
74              c = -p1.get_x();
75          }
76          else
77          {
78              p2.set_x(p1.get_x()+1);
79              p2.set_y(p1.get_y());
80              a = 0.0;
81              b = 1.0;
82              c = -p1.get_y();
83          }
84      }
85     
86     
87      Line::Line(const Line& l, double offset)
88      :p1(l.p1.get_x(),l.p1.get_y()+offset/fabs(sin(atan(l.slope())))),
89      p2(l.p2.get_x(),l.p2.get_y()+offset/fabs(sin(atan(l.slope()))))
90      {
91          if (slope() == HUGE_VAL)
92          {
93              a = 1.0;
94              b = 0.0;
95              c = -p1.get_x();
96          }
97          else
98          {
99              a = -slope();
100              b = 1.0;
101              c = slope()*p1.get_x()-p1.get_y();
102          }
103      }
104     
105     
106      // create an angled-length Line
107      Line::Line(const Point& p,double length, double angle)
108      :p1(p),p2(p1.get_x()+length*cos(angle),p1.get_y()+length*sin(angle))
109      {
110          if (slope() == HUGE_VAL)
111          {
112              a = 1.0;
113              b = 0.0;
114              c = -p1.get_x();
115          }
116          else
117          {
118              a = -slope();
119              b = 1.0;
120              c = slope()*p1.get_x()-p1.get_y();
121          }
122      }
123     
124     
125      void Line::print(void) const
126      {
127          cout << "Line  eqn: ";
128          if (a == 1.0) cout << 'x';
129          else if (a == -1.0) cout << "-x";
130          else if (a != 0.0) cout << a << 'x';
131          if ((a != 0.0) && (b != 0.0)) cout << " + ";
132          if (b == 1.0) cout << 'y';
133          else if (b == -1.0) cout << "-y";
134          else if (b != 0.0) cout << b << 'y';
135          if (c != 0.0) cout << " + " << c;
136          cout << " = 0";
137          cout << "  pts: ";
138          p1.print();
139          cout << ',';
140          p2.print();
141          cout << "  slope: " << slope() << endl;
142      }
143     
144     
145      double Line::length(void) const
146      {
147          return sqrt(square(p2.get_x()-p1.get_x())+square((p2.get_y()-p1.get_y())));
148      }
149     
150     
151      Point Line::midpoint() const
152      {
153          return Point((p1.get_x()+p2.get_x())/2,(p1.get_y()+p2.get_y())/2);
154      }
155     
156     
157      double Line::slope(void) const
158      {
159          if (!(p2.get_x()-p1.get_x())) return HUGE_VAL;
160          else return ((p2.get_y()-p1.get_y())/(p2.get_x()-p1.get_x()));
161      }
162     
163     
164      // returns distance from a Line to a Point
165      double Line::distance_to_Point(const Point& p) const
166      {
167          return (fabs(a*p.get_x()+b*p.get_y()+c)/
168              sqrt(square(a)+square(b)));
169      }
170     
171     
172      // returns distance between two parallel Lines
173      double Line::distance_to_Line(const Line& l) const
174      {
175          if (slope() != l.slope()) return 0.0;
176          else return distance_to_Point(l.p1);
177      }
178     
179     
180      double Line::x_intercept(void) const
181      {
182          if (a != 0.0) return -c/a;
183          else return HUGE_VAL;
184      }
185     
186     
187      double Line::y_intercept(void) const
188      {
189          if (b != 0.0) return -c/b;
190          else return HUGE_VAL;
191      }


1      // File: ex4-12m.cpp – main()
2     
3      #include <iostream>
4      #include <iomanip>        // for setprecision
5      using namespace std;
6     
7      #include "ex4-12p.h"
8      #include "ex4-12l.h"
9     
10     
11      const double pi = 3.14159265;
12     
13     
14      int main(void)
15      {
16          cout << setprecision(3) << endl;      // print with 3 decimal place accuracy
17     
18          Point origin;
19          Point p1(1.,2.);
20          Point p2(3.0,4.0);
21          Point p3(3.0,5.0);
22          Point p4(4.0,5.0);
23          Point p5(0.0,5.0);
24          Point p6(-2.0,3.0);
25     
26          Line l1(p1,p2);
27          Line l2(p2,p3);
28          Point p7(l1,l2);
29          Line l3(p3,p4);
30          Line l4(p5,p6);
31          Line l5(1.,2.,3.);
32          Line l6(p1,l4,"parallel");
33          Line l7(p1,l4,"perpendicular");
34          Line l8(p6,"vertical");
35          Line l9(p7,"horizontal");
36          Line l10(l4,1.0);
37          Line l11(l5,-2.0);
38          Line l12(origin,4.0,pi/3.0);
39          Line l13(p1,5.0,-pi/4.0);
40     
41          cout << "origin="; origin.print(); cout << endl;
42          cout << "p1="; p1.print(); cout << endl;
43          cout << "p2="; p2.print(); cout << endl;
44          cout << "p3="; p3.print(); cout << endl;
45          cout << "p4="; p4.print(); cout << endl;
46          cout << "p5="; p5.print(); cout << endl;
47          cout << "p6="; p6.print(); cout << endl;
48          cout << "p7="; p7.print(); cout << endl;
49          cout << "l1-"; l1.print();
50          cout << "l1 (x-intercept): " << l1.x_intercept()
51              << "   (y-intercept): " << l1.y_intercept() << endl;
52          cout << "l2-";l2.print();
53          cout << "l3-";l3.print();
54          cout << "l4-";l4.print();
55          cout << "l5-";l5.print();
56          cout << "l6-";l6.print();
57          cout << "l7-";l7.print();
58          cout << "l8-";l8.print();
59          cout << "l9-";l9.print();
60          cout << "l10-";l10.print();
61          cout << "l11-";l11.print();
62          cout << "l12-";l12.print();
63          cout << "l13-";l13.print();
64     
65          cout << "length of l1 = " << l1.length() << endl;
66          cout << "length of l2 = " << l2.length() << endl;
67          cout << "midpoint of l1 = "; l1.midpoint().print(); cout << endl;
68          cout << "distance p1 to p2 = " << p1.distance_to_Point(p2) << endl;
69          cout << "distance p1 to p3 = " << p1.distance_to_Point(p3) << endl;
70          cout << "distance p1 to p4 = " << p1.distance_to_Point(p4) << endl;
71          cout << "distance p2 to p3 = " << p2.distance_to_Point(p3) << endl;
72          cout << "distance p1 to p1 = " << p1.distance_to_Point(p1) << endl;
73          cout << "distance l1 to p3 = " << l1.distance_to_Point(p3) << endl;
74          cout << "distance l1 to p4 = " << l1.distance_to_Point(p4) << endl;
75          cout << "distance l2 to p5 = " << l2.distance_to_Point(p5) << endl;
76          cout << "distance l3 to p6 = " << l3.distance_to_Point(p6) << endl;
77          cout << "distance l1 to l4 = " << l1.distance_to_Line(l4) << endl;
78          return 0;
79      }


****** Output (MS Visual C++ 2008) ******

origin=(0,0)
p1=(1,2)
p2=(3,4)
p3=(3,5)
p4=(4,5)
p5=(0,5)
p6=(-2,3)
p7=(3,4)
l1-Line  eqn: -x + y + -1 = 0  pts: (1,2),(3,4)  slope: 1
l1 (x-intercept): -1   (y-intercept): 1
l2-Line  eqn: x + -3 = 0  pts: (3,4),(3,5)  slope: 1.#J
l3-Line  eqn: y + -5 = 0  pts: (3,5),(4,5)  slope: 0
l4-Line  eqn: -x + y + -5 = 0  pts: (0,5),(-2,3)  slope: 1
l5-Line  eqn: x + 2y + 3 = 0  pts: (-3,0),(0,-1.5)  slope: -0.5
l6-Line  eqn: x + -y + 1 = 0  pts: (1,2),(0,1)  slope: 1
l7-Line  eqn: -x + -y + 3 = 0  pts: (1,2),(0,3)  slope: -1
l8-Line  eqn: x + 2 = 0  pts: (-2,3),(-2,4)  slope: 1.#J
l9-Line  eqn: y + -4 = 0  pts: (3,4),(4,4)  slope: 0
l10-Line  eqn: -x + y + -6.41 = 0  pts: (0,6.41),(-2,4.41)  slope: 1
l11-Line  eqn: 0.5x + y + 5.97 = 0  pts: (-3,-4.47),(0,-5.97)  slope: -0.5
l12-Line  eqn: -1.73x + y = 0  pts: (0,0),(2,3.46)  slope: 1.73
l13-Line  eqn: 1x + y + -3 = 0  pts: (1,2),(4.54,-1.54)  slope: -1
length of l1 = 2.83
length of l2 = 1
midpoint of l1 = (2,3)
distance p1 to p2 = 2.83
distance p1 to p3 = 3.61
distance p1 to p4 = 4.24
distance p2 to p3 = 1
distance p1 to p1 = 0
distance l1 to p3 = 0.707
distance l1 to p4 = 0
distance l2 to p5 = 3
distance l3 to p6 = 2
distance l1 to l4 = 2.83


****** Output (gcc version 4.3.2 (GCC) undex Linux) ******

Compile command:  g++ ex4-12*.cpp -Wall

****** Output ******

origin=(0,0)
p1=(1,2)
p2=(3,4)
p3=(3,5)
p4=(4,5)
p5=(0,5)
p6=(-2,3)
p7=(3,4)
l1-Line  eqn: -x + y + -1 = 0  pts: (1,2),(3,4)  slope: 1
l1 (x-intercept): -1   (y-intercept): 1
l2-Line  eqn: x + -3 = 0  pts: (3,4),(3,5)  slope: inf
l3-Line  eqn: y + -5 = 0  pts: (3,5),(4,5)  slope: 0
l4-Line  eqn: -x + y + -5 = 0  pts: (0,5),(-2,3)  slope: 1
l5-Line  eqn: x + 2y + 3 = 0  pts: (-3,0),(0,-1.5)  slope: -0.5
l6-Line  eqn: x + -y + 1 = 0  pts: (1,2),(0,1)  slope: 1
l7-Line  eqn: -x + -y + 3 = 0  pts: (1,2),(0,3)  slope: -1
l8-Line  eqn: x + 2 = 0  pts: (-2,3),(-2,4)  slope: inf
l9-Line  eqn: y + -4 = 0  pts: (3,4),(4,4)  slope: 0
l10-Line  eqn: -x + y + -6.41 = 0  pts: (0,6.41),(-2,4.41)  slope: 1
l11-Line  eqn: 0.5x + y + 5.97 = 0  pts: (-3,-4.47),(0,-5.97)  slope: -0.5
l12-Line  eqn: -1.73x + y = 0  pts: (0,0),(2,3.46)  slope: 1.73
l13-Line  eqn: 1x + y + -3 = 0  pts: (1,2),(4.54,-1.54)  slope: -1
length of l1 = 2.83
length of l2 = 1
midpoint of l1 = (2,3)
distance p1 to p2 = 2.83
distance p1 to p3 = 3.61
distance p1 to p4 = 4.24
distance p2 to p3 = 1
distance p1 to p1 = 0
distance l1 to p3 = 0.707
distance l1 to p4 = 0
distance l2 to p5 = 3
distance l3 to p6 = 2
distance l1 to l4 = 2.83

沒有留言:

張貼留言