通常的,关于一个类,包含了下面几个方面:
1 声明类成员和接口;2 定义类接口函数(方法)3通过接口调用类
下面先给出第一条:声明类成员和接口
1 # ifndef MYTIME0_H_ 2 # define MYTIME0_H_ 3 4 class Time 5 { 6 private: 7 int hours; 8 int minutes; 9 public: 10 Time(); 11 Time(int h, int m = 0); 12 void AddMin(int m); 13 void AddHr(int h); 14 void Reset(int h = 0, int m = 0); 15 Time Sum(const Time &t) const; 16 void Show() const; 17 18 }; 19 # endif
关于该类声明:
1 主要到类成员放在private中,类接口放在public中(private中的成员不允许通过外部对其访问)。很多时候,采用这样的方式使得逻辑更清晰
2 public声明中,有Time()函数,函数名Time和类名相同,说明这是构造函数,用于完成类初始化定义(在创建类对象之前,会首先调用构造函数初始化对象,然后才能生成对象)
3 public中,有两个Time()函数,他们均为构造函数,且使用了函数重载的功能(函数名相同,特征标不同),实际创建对象调用时会采取最佳匹配准则。
4 注意第15行代码,在类声明中,就允许产生该类定义的形参(这里是引用变量t),注意到,这里的函数的返回类型是Time类(创建类的初衷就是让类变的可以和基本类型一样操作自如,因此可以认为这里和int等没有区别)
疑惑:
A 搞清1,2,19行的代码究竟起到什么作用???
B 15,16行的代码,const为什么放在函数名的后面,有什么作用???
下面先给出第二条:定义类接口函数
1 # include "iostream" 2 # include "mytime0.h" 3 4 Time::Time() 5 { 6 hours = minutes = 0; 7 } 8 9 Time::Time(int h, int m) 10 { 11 hours = h; 12 minutes = m; 13 } 14 15 void Time::AddMin(int m) 16 { 17 minutes += m; 18 hours = minutes / 60; 19 minutes = minutes % 60; 20 } 21 22 void Time::AddHr(int h) 23 { 24 hours = hours + h; 25 } 26 27 void Time::Reset(int h, int m) 28 { 29 hours = h; 30 minutes = m; 31 } 32 33 Time Time::Sum(const Time &t)const 34 { 35 Time sum; 36 sum.minutes = minutes + t.minutes; 37 sum.hours = hours + t.hours + sum.minutes / 60; 38 sum.minutes = sum.minutes % 60; 39 return sum; 40 } 41 42 void Time::Show()const 43 { 44 using std::cout; 45 using std::endl; 46 std::cout << hours << "hours," << minutes << "minutes" << endl; 47 }
关于该类接口函数定义:
1 注意第二行,要将.h头文件包含进去,虽然这个cpp文件同样是头文件
2 注意在定义接口函数的时候,涉及到类作用域的问题,即我们所定义的接口函数,都是类中的函数,因此需要用类作用域限定接口函数,::为作用域运算符。(作用域保证了一个域内的东西和另一个域中同名的东西不会冲突)
3 两个Time()构造函数是没有函数返回类型的
4 注意,函数 返回类型 是写在 类名 前面的!!!
5 33-39行代码,请仔细分析:注意开头的两个Time,第一个表示函数的返回类型,第二个限定类作用域,参数采用引用变量可以占用更少的内存,因此在使用类这种复杂的数据结构的时候,通常会使用引用变量。
6 39行返回了一个Time类型的数据,要注意return返回的机制:返回结束返回之前,局部变量和临时对象会被销毁,(return 变量)则创建了变量的副本,返回副本值。所以这里不能返回Time&,即time引用。
7 类接口函数中,可以使用类成员变量。
小结:
不要返回指向局部变量或临时对象的引用。函数执行完毕后,局部变量会被销毁,引用将指向不存在的数据。
下面先给出第三条:通过接口调用类
1 # include "iostream" 2 # include"mytime0.h" 3 4 int main() 5 { 6 using std::cout; 7 using std::endl; 8 Time planning; 9 Time coding(2, 40); 10 Time fixing(5, 55); 11 Time total; 12 13 cout << "planninf time ="; 14 planning.Show(); 15 cout << endl; 16 17 cout << "coding time ="; 18 coding.Show(); 19 cout << endl; 20 21 cout << "fixing time ="; 22 fixing.Show(); 23 cout << endl; 24 25 total = coding.Sum(fixing); 26 cout << "total time ="; 27 total.Show(); 28 cout << endl; 29 30 system("pause"); 31 return 0; 32 33 }
关于该类调用:
1 开头仍然要包含类声明头文件
2 第8行代码声明planning对象时,构造函数使用第一个Time函数,9,10行声明时,采用第二个Time函数。
3 当我们看到coding.Show()这样的一行代码时,想到的应该是:首先,之前通过最优匹配的构造函数,初始化了coding对象的成员(这一步很关键),然后,show()方法可在其函数内部调用初始化好了的coding成员。
3 注意第25行代码:隐式调用了conding对象自己的成员,显示将fixing对象作为参数传递进去(承接3的描述)。