6.11 在构造函数中使用默认参数
图 6.1 time1.cpp
中的构造函数将 hour、minute 和 second 初始化为 0(即军用时间午夜11时)。
构造函数可以包含默认参数。图 6.8 重新定义 Time 的构造函数,该函数中每个变量的默认参数为0。通过提供构造函数默认参数,即使在构造函数调用中不提供数值,对象也能利用默认参数初始化为一致状态。程序员提供所有参数默认值(或显式不要求参数)的构造函数也称为默认构造函数(default constnlctor),即可以不用参数而调用的构造函数。一个类只能有一个默认构造函数。
1 // Fig. 6.8: time2.h
2 // Declaration of the Time class.
3 // Member functions are defined in time2.cpp
4
5 // preprocessor directives that
6 // prevent multiple inclusions of header file
7 #ifndef TIME2_H
8 #define TIME2_H
9
10 // Time abstract data type definition
11 class Time {
12 public:
13 Time( int = 0, int = 0, int = 0 ); // default constructor
14 void setTime( int, int, int ); // set hour, minute, second
15 void printMilitary(); // print military time format
16 void printStandard(); // print standard time format
17 private:
18 int hour; // 0 - 23
19 int minute; // 0 59
20 int second; // 0 - 59
21 };
22
23 #endif
24 // Fig. 6.8: time2.cpp
25 // Member function definitions for Time class.
26 #include <iostream.h>
27 #include "time2.h"
28
29 // Time constructor initializes each data member to zero.
30 // Ensures all Time objects start in a consistent state.
31 Time::Time(int hr,int min,int sec)
32 { setTime( hr, min, sec ); }
33
34 // Set a new Time value using military time. Perform validity
35 // checks on the data values. Set invalid values to zero.
36 void Time::setTime(int h,int m,int s)
37 {
38 hour = ( h >= 0 && h < 24 ) ? h : 0;
39 minute = ( m >0 && m < 60 )? m : 0;
40 second = ( s >= 0 && s < 60 ) ? s : 0;
41 }
42
43 // Print Time in military format
44 void Time::printMilitary()
45
46 cout << ( hour < 10 ? "O" : "" ) << hour << ":"
47 << ( minute < 10 ? "0" : "" ) << minute;
48 }
49
50 // Print Time in standard format
51 void Time::printStandard()
53 cout << ( ( hour == 0 || hour == 12 ) ? 12 : hour % 12 )
54 << ":" <<( minute < 10 ? "0" : "" ) << minute
55 << ":" << ( second < 10 ? "0" : "" ) << second
56 << ( hour < 12 ? "AM" : "PM" );
57 }
58 // Fig. 6.8: fig06_08.cpp
59 // Demonstrating a default constructor
60 // function for class Time.
61 #include<iostream.h>
62 #include "time2.h"
63
64 int main()
65 {
66 Time t1, // all arguments defaulted
67 t2(2), // minute and second defaulted
68 t3(21, 34), // second defaulted
69 t4(12, 25, 42), // all values specified
70 t5(27, 74, 99); // all bad values specified
71
72 cout << "Constructed with:\n"
73 << "all arguments defaulted:\n ";
74 t1.printMilitary();
75 cout << "\n ";
76 t1.printStandard();
77
78 cout << "\nhour specified; minute and second defaulted:"
79 << "\n ";
80 t2.printMilitary{);
81 cout << "\n ";
82 t2.printStandard();
83
84 cout << "\nhour and minute specified; second defaulted:"
85 << "\n ";
86 t3.printMilitary();
87 cout << "\n ";
88 t3.printStandard();
89
90 cout << "\nhour, minute, and second specified:"
91 << "\n ";
92 t4.printMilitaryO;
93 cout << "\n ";
94 t4.printStandard();
95
96 cout << "\nall invalid values specified:"
97 << "\n ";
98 t5.printMilitary();
99 cout << "\n ";
100 t5.printStandardO;
101 cout << endl;
102
103 return 0;
104 }
输出结果:
Constructed with:
all arguments defaulted
00:00
12:00:00 AM
hour specified; minute and second defaulted:
02:00
2:O0:0O AM
hour and minute specified; second defaulted:
21:34
9:34:00 PM
hour, minute, and second specified:
12:25
12:25:42 PM
all invalid values specified:
00:00
12:00:00 AM
图 6.8 构造函数使用默认参数
在这个程序中,构造函数调用成员函数 setTime,将数值传人构造函数(或用默认值)保证 hour 值取0到13、minute 和 second 值取0到59。如果数值超界,则 setTime 将其设置为0(使数据成员保证一致状态)。
注意,Time 构造函数也可以写成包含与setTime成员函数相同的语句。这样可能会使程序更有效,因为不必另外再调用 setTime 函数。但让 Time 构造函数和 setTime 成员函数使用相同代码会使程序维护更加困难。如果 setTime 成员函数的实现方法改变,则Time构造函数的实现方法也要相应 改变。Time 构造函数直接调用 setTime 时,setTime 成员函数的实现方法只要改变一次即可,这样就可以在改变实现方法时减少错误。另外,显式声明内联的构造函数或在类定义中定义构造函数也可以提高Time构造函数的性能(后者隐含内联函数定义)。
软件工程视点 6.19
如果类的成员函数已经提供类的构造函数(或其他成员函数)所需功能的所有部分,则从构造函数(或其他成员函数)调用这个成员函数。这样可以简化代码维护和减少修改代码实现方法时的出错机会。因此就形成了一个一般原则:避免重复代码。
编程技巧 6.6
只在头文件内的类定义的函数原型中声明默认函数参数值。
常见编程错误6.9
在头文件和成员函数定义中指定同一成员函数的默认初始化值。
图 6.8 的程序初始化五个 Time 对象:一个将三个参数指定为默认值,一个指定一个参数,一个指定两个参数.一个指定三个参数,一个指定三个无效参数。每个对象数据成员均显示实例化和初始化之后的内容。
如果类不定义构造函数,则编译器生成默认构造函数。这种构造函数不进行任何初始化,因此生成对象时,不能保证处于一致状态。
软件工程视点 6.20
类不一定有默认构造函数。