C++中使用类(重载,友元函数,转换函数等)

来源:互联网 发布:太平洋软件站官方网站 编辑:程序博客网 时间:2024/04/28 00:11

12点半了。好久没更新C++博文了。把一个章节看完了。接下来说下C++里的操作符重载和以后的内容。时间晚了,可能打字没打好。望大家见谅。

C++中有个operator操作符概念。如果想重载+运算符,那么需要写成operator+()。一般两个数相加是这么调用的:

[cpp] view plaincopyprint?
  1. a = b+c; == a = b.operator+(c);  

当调用操作符,会有一个隐式的调用。把自己的对象作为操作符的对象。然后显示调用参数c。

重点介绍友元函数。因为重载了运算符后可能出现类似:

[cpp] view plaincopyprint?
  1. a = 1.5 + c;  

此时按照上面的说法。1.5不是一个对象。无法完成操作,这时候就需要友元函数了,其实友元函数就是类的非成员函数,不会隐式的将自身对象也作为参数。

然后贴三段代码,注释写的还算详细。大家可以复制后去运行下看下结果。代码是从C++Primer Plus里抄过来的。

mytime0.h

[cpp] view plaincopyprint?
  1. #ifndef MYTIME0_H_  
  2. #define MYTIME0_H_  
  3. #include <iostream>  
  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. //  接下来时重载+运算符的函数  
  17.     Time operator+(const Time & t)const;      
  18.     void Show()const;  
  19. //  重载-运算符的函数  
  20.     Time operator-(const Time & t)const;  
  21. //  重载*运算符的函数  
  22.     Time operator*(double n)const;  
  23. //  友元函数  类似 a+b 的原型是 a.operator+(b); 所以如果 5*a 则5没有那个重载的函数,这时就不能使用类的成员函数了,需要友元函数来进行操作,类友元函数也就是非成员函数  
  24.     friend Time operator*(double m, const Time & t){return t * m;}  //内联函数,调用该类的成员函数,这里也就是上面那个函数。  
  25. //  友元函数。对于那些非成员重载操作符函数来说,操作符左面的操作数对应函数的第一个参数。类似 c = a+b 类似于 c = operator+(a,b)  
  26.     friend  std::ostream & operator<<(std::ostream & os, const Time & t);  
  27. };  
  28.   
  29. #endif  
mytime0.cpp
[cpp] view plaincopyprint?
  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 %= 60;  
  20. }  
  21.   
  22. void Time::AddHr(int h)  
  23. {  
  24.     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 %= 60;  
  39.     return sum;  
  40. }  
  41.   
  42. // 重载加号运算符的版本  
  43. Time Time::operator+(const Time & t)const  
  44. {  
  45.     Time sum;  
  46.     sum.minutes = minutes + t.minutes;  
  47.     sum.hours = hours + t.hours + sum.minutes/60;  
  48.     sum.minutes %= 60;  
  49.     return sum;  
  50. }  
  51.   
  52. Time Time::operator-(const Time & t)const  
  53. {  
  54.     Time diff;  
  55.     int tot1, tot2;  
  56.     tot1 = t.minutes + 60 * t.hours;  
  57.     tot2 = minutes + 60 * hours;  
  58.     diff.minutes = (tot2 - tot1) % 60;  
  59.     diff.hours = (tot2 - tot1) / 60;  
  60.     return diff;  
  61. }  
  62.   
  63. Time Time::operator*(double n)const  
  64. {  
  65.     Time result;  
  66.     long totalminutes = hours * n * 60 + minutes * n;  
  67.     result.hours = totalminutes / 60;  
  68.     result.minutes = totalminutes % 60;  
  69.     return result;  
  70. }  
  71.   
  72. std::ostream & operator<<(std::ostream & os, const Time & t)  
  73. {  
  74.     os << t.hours << "hours, " << t.minutes << " minutes";  
  75.     return os;  
  76. }  
  77.   
  78. void Time::Show()const  
  79. {  
  80.     std::cout << hours << " hours, " << minutes << " minutes";  
  81.       
  82. }  
  83.   
  84. //usetime0.cpp  
  85. #include <iostream>  
  86. #include "mytime0.h"  
  87.   
  88. int main()  
  89. {  
  90.     using std::cout;  
  91.     using std::endl;  
  92.     Time planning;  
  93.     Time coding(2, 40);  
  94.     Time fixing(5, 55);  
  95.     Time total;  
  96.   
  97.     cout << "planning time = ";  
  98.     planning.Show();  
  99.     cout << endl;  
  100.       
  101.     cout << "coding time = ";  
  102.     coding.Show();  
  103.     cout << endl;  
  104.   
  105.     cout << "fixing time = ";  
  106.     fixing.Show();  
  107.     cout << endl;  
  108.       
  109. //  total = coding.Sum(fixing);  
  110. //  重载加号运算符的版本  
  111.     total = coding + fixing;  
  112.     cout << "coding + fixing = ";  
  113.     total.Show();  
  114.     cout << endl;  
  115.   
  116.     Time morefixing(3 ,20);  
  117.     cout << "more fixing time = ";  
  118.     morefixing.Show();  
  119.     cout << endl;  
  120.     total = morefixing.operator+(total);  
  121.     cout << "morefixing.operator+(total) = ";  
  122.     total.Show();  
  123.     cout << endl;  
  124.   
  125.     Time aida(3, 35);  
  126.     Time tosca(2, 48);  
  127.     Time temp;  
  128.   
  129.     cout << "Aida and TOsca:\n";  
  130.     cout << aida <<"; " << tosca << endl;  
  131.     temp = aida + tosca;        // operator+()  
  132.     cout << "Aida + Tosca: " << temp << endl;  
  133.     temp = aida*1.17;  
  134.     cout << "Aida *1.17: " << temp << endl;  
  135.     cout << "10 * Tosca: " << 10 * tosca << endl;  
  136.   
  137.     return 0;  
  138. }  
然后接下来说下类的强制转换和自动转换。

类的自动转换就是,如果你定义了一个只接受一个参数的构造函数,那么在调用构造函数时,如果碰到匹配的参数,直接可以将一个基本类型转换为相应的类类型。其中有几种隐式转换的情况。

1.将某个对象初始化为某个值时。

2.将某个值赋值某个对象。

3.将某值传递给接收某对象参数的函数时。

4.返回值被声明为某个对象的函数返回一个某值时。

5.以上情况中,如果另一个值可以转化为某值时。

使用explicit关键字可以强制使用显式构造函数,可以避免把某值转化为某对象。

如果想进行相反的转换,那么就需要使用C++操作符函数-------转换函数。转换函数是用户自定义的强制类型转换。使用转换函数得注意以下三点:

1.转换函数必须是类方法。

2.转换函数不能指定返回类型。

3.转换函数不能有参数。

同样的,也上三段代码。

stonewt.h
[cpp] view plaincopyprint?
  1. #ifndef STONEWT_H_  
  2. #define STONEWT_H_  
  3. class Stonewt  
  4. {  
  5. private:  
  6.     enum{Lbs_per_stn = 14};  
  7.     int stone;  
  8.     double pds_left;  
  9.     double pounds;  
  10. public:  
  11.     Stonewt(double lbs);  
  12.     Stonewt(int stn, double lbs);  
  13.     Stonewt();  
  14.     ~Stonewt();  
  15.     void show_lbs()const;  
  16.     void show_stn()const;  
  17.   
  18.     // 转换函数,将对象转换为内置类型  
  19.     operator int()const;  
  20.     operator double()const;  
  21. };  
  22.   
  23. #endif  
stonewt.cpp

[cpp] view plaincopyprint?
  1. #include <iostream>  
  2. using std::cout;  
  3. #include "stonewt.h"  
  4.   
  5. Stonewt::Stonewt(double lbs)  
  6. {  
  7.     stone = int(lbs)/Lbs_per_stn;  
  8.     pds_left = int(lbs)%Lbs_per_stn + lbs - int(lbs);  
  9.     pounds = lbs;  
  10. }  
  11.   
  12. Stonewt::Stonewt(int stn, double lbs)  
  13. {  
  14.     stone = stn;  
  15.     pds_left = lbs;  
  16.     pounds = stn * Lbs_per_stn + lbs;  
  17. }  
  18.   
  19. Stonewt::Stonewt()  
  20. {  
  21.     stone = pounds = pds_left = 0;  
  22. }  
  23.   
  24. Stonewt::~Stonewt()  
  25. {  
  26. }  
  27.   
  28. void Stonewt::show_stn()const  
  29. {  
  30.     cout << stone << " stone." << pds_left << " pounds\n";  
  31. }  
  32.   
  33. void Stonewt::show_lbs()const  
  34. {  
  35.     cout << pounds << " pounds\n";  
  36. }  
  37.   
  38. // 转换方法 不带参数,不带返回值类型  
  39. Stonewt::operator int() const  
  40. {  
  41.     return int(pounds+0.5);  
  42. }  
  43.   
  44. Stonewt::operator double() const  
  45. {  
  46.     return pounds;    
  47. }  
stone.cpp

[cpp] view plaincopyprint?
  1. #include <iostream>  
  2. using std::cout;  
  3. #include "stonewt.h"  
  4. void display(const Stonewt st, int n);  
  5. int main()  
  6. {  
  7.     Stonewt pavarotti = 260;        //调用构造函数,因为260能转化为浮点型  
  8.     Stonewt wolfe(285.7);       //类似Stonewt wolfe = 285.7;  
  9.     Stonewt taft(21,8);  
  10.   
  11.     cout << "The tenor weighted ";  
  12.     pavarotti.show_stn();  
  13.     cout << "THe detective weighted ";  
  14.     wolfe.show_stn();  
  15.     cout << "The President weighed ";  
  16.     taft.show_lbs();  
  17.     pavarotti = 256.8;          //构造函数进行初始化  
  18.     taft = 325;             //和 taft = Stonewt(325);一样  
  19.     cout << "After dinner, the tenor weighed ";  
  20.     pavarotti.show_stn();  
  21.     cout << "After dinner, the president weighed ";  
  22.     taft.show_lbs();  
  23.     display(taft, 2);  
  24.     cout << "The wrestler weighted even more.\n";  
  25.     display(422, 2);            //将422转化乘 Stonewt对象  
  26.     cout << "No stone left unearned\n";  
  27.   
  28.     // 使用转换函数将类对象转化为基本类型  
  29.     Stonewt poppins(9, 28);  
  30.     double p_wt = poppins;  
  31.     cout << "COnvert to double => ";  
  32.     cout << "Poppins: " << p_wt << " pounds.\n";  
  33.     cout << "Convert to int => ";  
  34.     cout << "Poppins: " << int(poppins) << " pounds.\n";  
  35.     return 0;  
  36. }  
  37.   
  38. void display(const Stonewt st, int n)  
  39. {  
  40.     for (int i = 0; i < n; i++)  
  41.     {  
  42.         cout << "Wow! ";  
  43.         st.show_stn();  
  44.     }  
  45. }  

好了,写完就要1点了。准备休息,周末继续更新。