⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 06章 类与数据抽象(一).txt

📁 C++大学教程txt版中文版 C++大学教程txt版中文版
💻 TXT
📖 第 1 页 / 共 5 页
字号:
6.10  初始化类对象:构造函数
    生成类对象时,其成员可以用类的构造函数初始化。构造函数是与类同名的成员函数。程序员提供的构造函数在每次生成类对象(实例化)时自动调用。构造函数可以重载.提供初始化类对象的不同方法。数据成员应在类的构造函数中初始化或在生成对象之后设置其数值。

    常见编程错误6. 7
    类的数据成员只能在类定义中初始化。

    常见编程错误6.8
    试图声明构造函数的返回类型和返回植是个语法错误。
    
    编程技巧6.5
    适当时候(通常都是)应提供一十构速函数,保证每个对象正确地初始化为有意义的值。特别是指针数
据类型应初始化为合法指针值或0。

    测试与调试提示6.4
    每个修改对象的private数据成员的成员函数(和友元)应确保数据保持一致状态。
    声明类对象时,可以在括号中提供初始化值,放在对象名后面和分号前面。这些初始化值作为

参数传递给类的构造函数。稍后会举几个构造函数调用(constructor call)的例子(注意:尽管程序
员不显式调用构造函数,但程序员仍然可以提供数据,作为参数传递给构造函数)。

6.11  在构造函数中使用默认参数
    图6.1time1.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
    类不一定有默认构造函数。

6.12  使用析构函数
    析构函数是类的特殊成员函数。类的析构函数名是类名前面加上代字符(~)这种命名规则很直观,因为本章稍后将会介绍,代字运算符是按位取反符,从这个意义上,析构函数是构造函数的反函数。
    类的析构函数在删除对象时调用,即程序执行离开初始化类对象的范围时。析构函数本身并不实际删除对象,而是进行系统放弃对象内存之前的清理工作,使内存可以复用于保存新对象。
    析构函数不接受参数也不返回数值。类只可能有一个析构函数,不能进行析构函数重载。常见编程错误6.10
    向析构函数传递参数、指定析构函数的返回值类型(即使指定void)、从析构函数返回数值或重载析构函数都是语法错误。
    注意,前面介绍的类都没有提供析构函数。下面要介绍几个使用析构函数的例子。第8章将介绍析构函数适用于动态分配内存的对象类(例如数组和字符串)。第7章将介绍如何动态分配内存和释放内存。

    软件工程视点6.21
    稍后会介招,构造函数和析构函数在C++和面向对象编程中相当重要,不是这里的介绍所能说清楚的。

6.13  何时调用构造函数与析构函数
    构造函数与析构函数是自动调用的。这些函数的调用顺序取决于执行过程进入和离开实例化对象范围的顺序。一般来说,析构函数的调用顺序与构造函数相反。但图6.9将介绍对象存储类可以改变析构函数的调用顺序。
  全局范围中定义的对象的构造函数在文件中的任何其他函数(包括main)执行之前调用(但不同文件之间全局对象构造函数的执行顺序是不确定的)。当main终止或调用exit函数时(见第18章)调用相应的析构函数。
    当程序执行到对象定义时,调用自动局部对象的构造函数。该对象的析构函数在对象离开范围时调用(即离开定义对象的块时)。自动对象的构造函数与析构函数在每次对象进人和离开范围时调用。
    static局部对象的构造函数只在程序执行首次到达对象定义时调用一次,对应的析构函数在main终止或调用exit函数时调用。
    图6.9的程序演示了CreateAndDestroy类型的对象在几种范围中调用构造函数与析构函数的顺序。程序在全局范围中定义first,其构造函数在程序开始执行时调用,其析构函数在程序终止时删除所有其他对象之后调用。

1 // Fig. 6,9: create,h
2 // Definition of class CreateAndDestroy.
3 // Member functions defined in create.cpp,
4 #ifndef CREATE_H
5 #define CREATE_H
6
7 class CreateAndDestroy {
8 public:
9   CreateAndDestroy( int );  // constructor
10   ~CreateAndDestroy();     // destructor
11 private:
12   int data;
13 };
14
15 #endif
16 // Fig, 6.9: create.cpp
17 // Member function definitions for class CreateAndDestroy
18 #include <iostream.h>
19 #include "create.h"
20
21 CreateAndDestroy::CreateAndDestroy( int value )
22 {
23    data = value;
24     cout << "Object "<< data <<"  constructor";
29 }
26
27 CreateAndDestroy::~CreateAndDestroyO
28   { cout << "Object "<< data <<"  destructor "<< endl; }
29 // Fig, 6.9: fig0609.cpp
30 // Demonstrating the order in which constructors and
31 // destructors are called.
32 #include <iostream.h>
39 #include "create.h"
34
35 void create( void );  // prototype
36
37 CreateAndDestroy first( 1 );  // global object
38
39 int main()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -