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
沒有留言:
張貼留言