C++primer第十一章使用类(矢量随机游走实例)

打印 上一主题 下一主题

主题 1734|帖子 1734|积分 5202

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
操作符重载

操作符重载(operator overoading)是一种情势的 C++多态。
第8章介绍了C++是如何使用户能够界说多个名称雷同但特性标(参数列表)不同的函数的。这被称为函数重载(function overloading)或函数多态(functional polymorphism),旨在让您能够用同名的函数来完成雷同的基本操作,即使这种操作被用于不同的数据范例
现实上,许多 C++(也包括C语言)操作符已经被重载。比方,将*操作符用于地址,将得到存储在这个地址中的值;但将它用于两个数字时,得到的将是它们的乘积。C++根据操作数的数目和范例来决定接纳哪种操作。
数组加法


op是将要重载的操作符。比方,operator +()重载+操作符,operator*()重载*操作符。op 必须是有效的 C++操作符,不能虚构一个新的符号。比方,不能有 operator@()这样的函数,由于 C++中没有@操作符。
操作符重载范例

mytime0.h
  1. // mytime0.h-- Time class before operator overloading
  2. #ifndef MYTIMEO H
  3. #define MYTIMEO H
  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. #endif
复制代码
Sum()函数的代码。注意参数是引用,但返回范例却不是引用。将参数声明为引用的目的是为了进步服从。如果按值传递Time 对象,代码的功能将雷同,但传递引用,速度将更快,使用的内存将更少。

mytime0.cpp
  1. // mytime0.cpp--implement Time methods
  2. #include <iostream>
  3. #include "mytime0.h"
  4. Time::Time()
  5. {
  6.     hours = minutes = 0;
  7. }
  8. Time::Time(int h, int m)
  9. {
  10.     hours = h;
  11.     minutes = m;
  12. }
  13. void Time::AddMin(int m)
  14. {
  15.     minutes += m;
  16.     hours += minutes / 60;
  17.     minutes %= 60;
  18. }
  19. void Time::AddHr(int h)
  20. {
  21.     hours += h;
  22. }
  23. void Time::Reset(int h, int m)
  24. {
  25.     hours = h;
  26.     minutes = m;
  27. }
  28. Time Time::Sum(const Time &t) const
  29. {
  30.     Time sum;
  31.     sum.minutes = minutes + t.minutes;
  32.     sum.hours = hours + t.hours + sum.minutes / 60;
  33.     sum.minutes %= 60;
  34.     return sum;
  35. }
  36. void Time::Show() const
  37. {
  38.     std::cout << hours << " hours. " << minutes << "minutes";
  39. }
复制代码
usetime0.cpp
  1. #include <iostream>
  2. #include "mytime0.h"
  3. int main()
  4. {
  5.     using std::cout;
  6.     using std::endl;
  7.     Time planning;
  8.     Time coding(2, 40);
  9.     Time fixing(5, 55);
  10.     Time total;
  11.     cout << "planning time =";
  12.     planning.Show();
  13.     cout << endl;
  14.     cout << "coding time =";
  15.     coding.Show();
  16.     cout << endl;
  17.     cout << "fixing time =";
  18.     fixing.Show();
  19.     cout << endl;
  20.     total = coding.Sum(fixing);
  21.     cout << "coding.Sum(fixing)=";
  22.     total.Show();
  23.     return 0;
  24. }
复制代码

添加加法操作符

将 Time 类转换为重载的加法操作符很容易,只要将 Sum()的名称改为 operator+()即可。这样做是对的,只要把操作符(这里为+)放到operator的背面,并将结果用作方法名即可。在这里,可以在标识符中使用字母、数字或下划线之外的其他字符。
mytime1.h
  1. // mytime0.h-- Time class before operator overloading
  2. #ifndef MYTIMEO H
  3. #define MYTIMEO H
  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.     Time operator+(const Time &t) const;
  17.     void Show() const;
  18. };
  19. #endif
复制代码
mytime1.cpp
  1. // mytime0.cpp--implement Time methods
  2. #include <iostream>
  3. #include "mytime0.h"
  4. Time::Time()
  5. {
  6.     hours = minutes = 0;
  7. }
  8. Time::Time(int h, int m)
  9. {
  10.     hours = h;
  11.     minutes = m;
  12. }
  13. void Time::AddMin(int m)
  14. {
  15.     minutes += m;
  16.     hours += minutes / 60;
  17.     minutes %= 60;
  18. }
  19. void Time::AddHr(int h)
  20. {
  21.     hours += h;
  22. }
  23. void Time::Reset(int h, int m)
  24. {
  25.     hours = h;
  26.     minutes = m;
  27. }
  28. Time Time::operator+(const Time &t) const
  29. {
  30.     Time sum;
  31.     sum.minutes = minutes + t.minutes;
  32.     sum.hours = hours + t.hours + sum.minutes / 60;
  33.     sum.minutes %= 60;
  34.     return sum;
  35. }
  36. void Time::Show() const
  37. {
  38.     std::cout << hours << " hours. " << minutes << "minutes";
  39. }
复制代码
usetime1.cpp
  1. #include <iostream>
  2. #include "mytime0.h"
  3. int main()
  4. {
  5.     using std::cout;
  6.     using std::endl;
  7.     Time planning;
  8.     Time coding(2, 40);
  9.     Time fixing(5, 55);
  10.     Time total;
  11.     cout << "planning time =";
  12.     planning.Show();
  13.     cout << endl;
  14.     cout << "coding time =";
  15.     coding.Show();
  16.     cout << endl;
  17.     cout << "fixing time =";
  18.     fixing.Show();
  19.     cout << endl;
  20.     total = coding + fixing;
  21.     cout << "coding + fixing=";
  22.     total.Show();
  23.     cout << endl;
  24.     Time morefixing(3, 28);
  25.     cout << "more fixing time = ";
  26.     morefixing.Show();
  27.     cout << endl;
  28.     total = morefixing.operator+(total); // function notation
  29.     cout << "morefixing.operator+(total)=";
  30.     total.Show();
  31.     cout << endl;
  32.     return 0;
  33. }
复制代码


重载限制

重载的操作符(有些例外情况)不必是成员函数,但必须至少有一个操作数是用户界说的范例







其他重载操作符

时间的减和乘

mytime2.h
  1. // mytime0.h-- Time class before operator overloading
  2. #ifndef MYTIMEO H
  3. #define MYTIMEO H
  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.     Time operator+(const Time &t) const;
  17.     Time operator-(const Time &t) const;
  18.     Time operator*(double n) const;
  19.     void Show() const;
  20. };
  21. #endif
复制代码
mytime2.cpp
  1. // mytime0.cpp--implement Time methods
  2. #include <iostream>
  3. #include "mytime0.h"
  4. Time::Time()
  5. {
  6.     hours = minutes = 0;
  7. }
  8. Time::Time(int h, int m)
  9. {
  10.     hours = h;
  11.     minutes = m;
  12. }
  13. void Time::AddMin(int m)
  14. {
  15.     minutes += m;
  16.     hours += minutes / 60;
  17.     minutes %= 60;
  18. }
  19. void Time::AddHr(int h)
  20. {
  21.     hours += h;
  22. }
  23. void Time::Reset(int h, int m)
  24. {
  25.     hours = h;
  26.     minutes = m;
  27. }
  28. Time Time::operator+(const Time &t) const
  29. {
  30.     Time sum;
  31.     sum.minutes = minutes + t.minutes;
  32.     sum.hours = hours + t.hours + sum.minutes / 60;
  33.     sum.minutes %= 60;
  34.     return sum;
  35. }
  36. Time Time::operator-(const Time &t) const
  37. {
  38.     Time diff;
  39.     int tot1, tot2;
  40.     tot1 = t.minutes + 60 * t.hours;
  41.     tot2 = minutes + 60 * hours;
  42.     diff.minutes = (tot2 - tot1) % 60;
  43.     diff.hours = (tot2 - tot1) / 60;
  44.     return diff;
  45. }
  46. Time Time::operator*(double mult) const
  47. {
  48.     Time result;
  49.     long totalminutes = (minutes + 60 * hours) * mult;
  50.     result.minutes = totalminutes % 60;
  51.     result.hours = totalminutes / 60;
  52.     return result;
  53. }
  54. void Time::Show() const
  55. {
  56.     std::cout << hours << " hours. " << minutes << "minutes";
  57. }
复制代码
usetime2.cpp
  1. #include <iostream>
  2. #include "mytime0.h"
  3. int main()
  4. {
  5.     using std::cout;
  6.     using std::endl;
  7.     Time weeding(4, 35);
  8.     Time waxing(2, 47);
  9.     Time total;
  10.     Time diff;
  11.     Time adjusted;
  12.     cout << "weeding time =";
  13.     weeding.Show();
  14.     cout << endl;
  15.     cout << "waxing time =";
  16.     waxing.Show();
  17.     cout << endl;
  18.     cout << "total time =";
  19.     total = weeding + waxing;
  20.     cout << "coding + fixing=";
  21.     total.Show();
  22.     cout << endl;
  23.     diff = weeding - waxing;
  24.     cout << "coding - fixing=";
  25.     diff.Show();
  26.     cout << endl;
  27.     adjusted = total * 1.5;
  28.     cout << "Adjusted work time = ";
  29.     total.Show();
  30.     cout << endl;
  31.     return 0;
  32. }
复制代码

友元简介

C++控制对类对象私有部分的访问。通常,公有类方法提供惟一的访问途径,但是有时间这种限制太严格,以致上不恰当特定的编程题目。在这种情况下,C++提供了另外一种情势的访问权限:
友元。
友元有三种:

介绍如何成为友元之前,先介绍为何需要友元。在为类重载一元操作符时(带两个参数的操作符)常常需要友元。将Time对象乘以实数就属于这种情况

从概念上说,2.75*B应与 B*2.75 雷同,但第一个表达式不对应于成员函数,由于 2.75 不是 Time 范例的对象。记着,左侧的操作数应是调用对象,但2.75不是对象。因此,编译器不能使用成员函数调用来替换该表达式。
决这个难题的一种方式是,告知每个人(包括程序员本身),只能按B*2.75 这种格式编写,不能写成 2.75*B。这是一种对服务器友爱-客户警惕的(server-ffiendly,client-beware)办理方案,与OOP无关。


(无法直接访问B中的内容)
创建友元

创建友元函数的第是将其原型放在类声明中,并在原型声明前加上关键字friend



第二步是编写函数界说。由于它不是成员函数,以是不要使用Time:限定符。另外,不要在界说中使用关键字 friend,界说应该如下:



常用的友元:重载<<操作符


 之以是可以这样做,是由于<<是可被重载的 C++操作符之一
前面讲过,cout 是一个 ostream 对象,它是智能的,能够辨认全部的 C++基本范例。这是由于对于每种基本范例,ostream类声明中都包含了相应的重载的 operator<<()界说
因此,要使 cout 能够辨认 Time 对象,一种方法是将一个新的函数操作符界说添加到 ostream 类声明中。但修改iostream 文件是个伤害的主意,这样做会在尺度接口上浪费时间。更好的办法是,通过Time类声明来让 Time 类知道如何使用 cout
<<第一种重载版本


司用 cout<<trip 应使用cout对象本身,而不是它的拷贝,因此该函数按引用(而不是按值)来传递该对象。这样,表达式 cout<<trip 将导致 os 成为 cout 的一个别名;而表达式 cenr <<trip 将导致 os 成为 cen
的一个别名。Time对象可以按值或按引用来传递,由于这两种情势都使函数能够使用对象的值。按引用传递使用的内存和时间都比按值传递少。
<<第二种重载版本

题目:

比方


修改方法

调用os类的引用以是

特殊的

头文件
  1. // mytime0.h-- Time class before operator overloading
  2. #ifndef MYTIME0_H_
  3. #define MYTIME0_H_
  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.     Time operator+(const Time &t) const;
  17.     Time operator-(const Time &t) const;
  18.     Time operator*(double n) const;
  19.     friend Time operator*(double m, const Time &t)
  20.     {
  21.         return t * m;
  22.     } // inline definition
  23.     friend std::ostream &operator<<(std::ostream &os, const Time &t);
  24. };
  25. #endif
复制代码
其中包括 operator*()和 operator<<()这两个友元函数。它将第-个友元函数作为内联函数,由于其代码很短(当界说同时也是原型时,就像这个例子中那样,要使用 fiend前缀)。
源代码
  1. // mytime0.cpp--implement Time methods
  2. #include <iostream>
  3. #include "mytime0.h"
  4. Time::Time()
  5. {
  6.     hours = minutes = 0;
  7. }
  8. Time::Time(int h, int m)
  9. {
  10.     hours = h;
  11.     minutes = m;
  12. }
  13. void Time::AddMin(int m)
  14. {
  15.     minutes += m;
  16.     hours += minutes / 60;
  17.     minutes %= 60;
  18. }
  19. void Time::AddHr(int h)
  20. {
  21.     hours += h;
  22. }
  23. void Time::Reset(int h, int m)
  24. {
  25.     hours = h;
  26.     minutes = m;
  27. }
  28. Time Time::operator+(const Time &t) const
  29. {
  30.     Time sum;
  31.     sum.minutes = minutes + t.minutes;
  32.     sum.hours = hours + t.hours + sum.minutes / 60;
  33.     sum.minutes %= 60;
  34.     return sum;
  35. }
  36. Time Time::operator-(const Time &t) const
  37. {
  38.     Time diff;
  39.     int tot1, tot2;
  40.     tot1 = t.minutes + 60 * t.hours;
  41.     tot2 = minutes + 60 * hours;
  42.     diff.minutes = (tot2 - tot1) % 60;
  43.     diff.hours = (tot2 - tot1) / 60;
  44.     return diff;
  45. }
  46. Time Time::operator*(double mult) const
  47. {
  48.     Time result;
  49.     long totalminutes = (minutes + 60 * hours) * mult;
  50.     result.minutes = totalminutes % 60;
  51.     result.hours = totalminutes / 60;
  52.     return result;
  53. }
  54. std::ostream &operator<<(std::ostream &os, const Time &t)
  55. {
  56.     os << t.hours << " hours, " << t.minutes << " minutes";
  57.     return os;
  58. }
复制代码
源代码
  1. #include <iostream>
  2. #include "mytime0.h"
  3. int main()
  4. {
  5.     using std::cout;
  6.     using std::endl;
  7.     Time aida(3, 35);
  8.     Time tosca(2, 48);
  9.     Time temp;
  10.     cout << "Aida and Tosca:\n";
  11.     cout << aida << ";" << tosca << endl;
  12.     temp = aida + tosca; // operator+()
  13.     cout << "Aida + Tosca:" << temp << endl;
  14.     temp = aida * 1.17; // member operator*()
  15.     cout << "Aida*l.17:" << temp << endl;
  16.     cout << "10*Tosca:" << 10 * tosca << endl;
  17.     return 0;
  18. }
复制代码

重载操作符:作为成员函数还是非成员函数

两种加法操作符


对于两种加法

界说操作符时间只能使用其中一种格式,否则会产生歧义。
重载:矢量类



头文件
  1. // vect.h--Vector class with<<,mode state
  2. #ifndef VECTOR_H_
  3. #define VECTOR_H_
  4. #include <iostream>
  5. namespace VECTOR
  6. {
  7.     class Vector
  8.     {
  9.     private:
  10.         double x;
  11.         double y;
  12.         double mag;
  13.         char mode;
  14.         double ang;
  15.         void set_mag();
  16.         void set_ang();
  17.         void set_x();
  18.         void set_y();
  19.     public:
  20.         Vector();
  21.         Vector(double nl, double n2, char form = 'r');
  22.         void set(double nl, double n2, char form = 'r');
  23.         ~Vector();
  24.         double xval() const { return x; }     // report x value
  25.         double yval() const { return y; }     // report y value
  26.         double magval() const { return mag; } // report magnitude
  27.         double angval() const { return ang; } // report angle
  28.         void polar_mode();
  29.         void rect_mode(); // operator overloading
  30.         Vector operator+(const Vector &b) const;
  31.         Vector operator-(const Vector &b) const;
  32.         Vector operator-() const;
  33.         Vector operator*(double n) const;
  34.         friend Vector operator*(double n, const Vector &a);
  35.         friend std::ostream &operator<<(std::ostream &os, const Vector &v);
  36.     };
  37. } // end namespace VECTOR
  38. #endif
复制代码
源代码
  1. // vector.cpp --methods for Vector class
  2. #include <cmath>
  3. #include "vector.h"
  4. #include <iostream>
  5. using std::atan2;
  6. using std::cos;
  7. using std::cout;
  8. using std::sin;
  9. namespace VECTOR
  10. {
  11.     const double Rad_to_deg = 57.2957795130823;
  12.     // private methods
  13.     // calculates magnitude from x and y
  14.     void Vector::set_mag()
  15.     {
  16.         mag = sqrt(x * x + y * y);
  17.     }
  18.     void Vector::set_ang()
  19.     {
  20.         if (x == 0.0 && y == 0.0)
  21.             ang = 0.0;
  22.         else
  23.             ang = atan2(y, x);
  24.     }
  25.     // set xfrom polar coordinate
  26.     void Vector::set_x()
  27.     {
  28.         x = mag * cos(ang);
  29.     }
  30.     // set y from polar coordinate
  31.     void Vector::set_y()
  32.     {
  33.         y = mag * sin(ang);
  34.     }
  35.     // public methods
  36.     Vector::Vector() // default constructor
  37.     {
  38.         x = y = mag = ang = 0.0;
  39.         mode = 'r';
  40.     }
  41.     Vector::Vector(double n1, double n2, char form)
  42.     {
  43.         mode = form;
  44.         if (form == 'r')
  45.         {
  46.             x = n1;
  47.             y = n2;
  48.             set_mag();
  49.             set_ang();
  50.         }
  51.         else if (form == 'p')
  52.         {
  53.             mag = n1;
  54.             ang = n2 / Rad_to_deg;
  55.             set_x();
  56.             set_y();
  57.         }
  58.         else
  59.         {
  60.             cout << "Incorrect 3rd argument to Vector()-- ";
  61.             cout << "vector set to 0\n";
  62.             x = y = mag = ang = 0.0;
  63.             mode = 'r';
  64.         }
  65.     }
  66.     // set vector from rectangular coordinates if form is r(the
  67.     // default)or else from polar coordinates if form is p
  68.     void Vector::set(double n1, double n2, char form)
  69.     {
  70.         mode = form;
  71.         if (form == 'r')
  72.         {
  73.             x = n1;
  74.             y = n2;
  75.             set_mag();
  76.             set_ang();
  77.         }
  78.         else if (form == 'p')
  79.         {
  80.             mag = n1;
  81.             ang = n2 / Rad_to_deg;
  82.             set_x();
  83.             set_y();
  84.         }
  85.         else
  86.         {
  87.             cout << "Incorrect 3rd argument to Vector()-- ";
  88.             cout << "vector set to 0\n";
  89.             x = y = mag = ang = 0.0;
  90.             mode = 'r';
  91.         }
  92.     }
  93.     Vector::~Vector()
  94.     {
  95.     } // destructor
  96.     void Vector::polar_mode() // set to polar  mode
  97.     {
  98.         mode = 'p';
  99.     }
  100.     void Vector::rect_mode() // set to rectangular mode
  101.     {
  102.         mode = 'r';
  103.     }
  104.     // operator overloading
  105.     //  add two Vectors
  106.     Vector Vector::operator+(const Vector &b) const
  107.     {
  108.         return Vector(x + b.x, y + b.y);
  109.     }
  110.     // subtract Vector b from a
  111.     Vector Vector::operator-(const Vector &b) const
  112.     {
  113.         return Vector(x - b.x, y - b.y);
  114.     }
  115.     // reverse sign of Vector
  116.     Vector Vector::operator-() const
  117.     {
  118.         return Vector(-x, -y);
  119.     }
  120.     // multiple vector by n
  121.     Vector Vector::operator*(double n) const
  122.     {
  123.         return Vector(n * x, n * y);
  124.     }
  125.     // friend methods
  126.     // multiply n byVector a
  127.     Vector operator*(double n, const Vector &a)
  128.     {
  129.         return a * n;
  130.     }
  131.     // display rectangular coordinates if mode is r
  132.     // else display polar coordinates if mode is p
  133.     std::ostream &operator<<(std::ostream &os, const Vector &v)
  134.     {
  135.         if (v.mode == 'r')
  136.         {
  137.             os << "(x,y)=(" << v.x << "," << v.y << ")";
  138.         }
  139.         else if (v.mode == 'p')
  140.         {
  141.             os << "(m,a)=(" << v.mag << ","
  142.                << v.ang * Rad_to_deg << ")";
  143.         }
  144.         else
  145.             os << "Vector object mode is invalid";
  146.         return os;
  147.     }
  148. } // end namespace VECTOR
复制代码
使用状态成员

状态成员

为Vector类重载操作符

加法

可以使用的加法(无法使用极坐标)

改进

接纳的加法(简单)

乘法


友元内联函数来办理乘法交换次序的题目

对已重载的操作符进行重载

减法(二元操作符)

取反(一元操作符)

模拟随机游走

  1. // randwalk.cpp-…using the Vector class
  2. // compile with the vect.cpp file
  3. #include <iostream>
  4. // rand(),srand()prototypes// time()prototype
  5. #include <cstdlib>
  6. #include <ctime>
  7. #include "vector.h"
  8. int main()
  9. {
  10.     using namespace std;
  11.     using VECTOR::Vector;
  12.     srand(time(0)); // seed random - number generator
  13.     double direction;
  14.     Vector step;
  15.     Vector result(0.0, 0.0);
  16.     unsigned long steps = 0;
  17.     double target;
  18.     double dstep;
  19.     cout << "Enter target distance(q to quit):";
  20.     while (cin >> target)
  21.     {
  22.         cout << "Enter step length:";
  23.         if (!(cin >> dstep))
  24.             break;
  25.         while (result.magval() < target)
  26.         {
  27.             direction = rand() % 360;
  28.             step.set(dstep, direction, 'p');
  29.             result = result + step;
  30.             steps++;
  31.         }
  32.         cout << "After " << steps << " steps, the subject"
  33.                                      " has the following location : \n ";
  34.         cout << result << endl;
  35.         result.polar_mode();
  36.         cout << " or\n " << result << endl;
  37.         cout << " Average outward distance per step = "
  38.              << result.magval() / steps << endl;
  39.         steps = 0;
  40.         result.set(0.0, 0.0);
  41.         cout << "Enter target distance(qto quit):";
  42.     }
  43.     cout << "Bye!\n";
  44.     return 0;
  45. }
复制代码

类的主动转换和强制范例转换

内置范例转换

将一个尺度范例变量的值赋给另一种尺度范例的变量时,如果这两种范例兼容,则C++主动将这个值转换为吸收变量的范例。
比方

不兼容的范例不能主动转换

但是可以进行强制范例转换

类的转换

可以将类界说成与基本范例或另一个类相关,使得从一种范例转换为另一种范例是故意义的。
stonewt.h
  1. // stonewt.h --definition forStonewtCass
  2. #ifndef STONEWT_H_
  3. #define STONEWT_H_
  4. class Stonewt
  5. {
  6. private:
  7.     enum
  8.     {
  9.         Lbs_per_stn = 14
  10.     }; // pounds per stone
  11.     int stone;       // whole stones
  12.     double pds_left; // fractional pounds
  13.     double pounds;   // entire weight in pounds
  14. public:
  15.     Stonewt(double lbs);          // constructor for double pounds
  16.     Stonewt(int stn, double lbs); // constructor for stone,1bs
  17.     Stonewt();                    // default constructor
  18.     ~Stonewt();
  19.     void show_lbs() const;
  20.     // show weight in pounds format
  21.     void show_stn() const;
  22.     // show weight in stone format}
  23. };
  24. #endif
复制代码

源文件
  1. #include <iostream>
  2. using std::cout;
  3. #include "stonewt.h"
  4. // construct Stonewt object from double value
  5. Stonewt::Stonewt(double lbs)
  6. {
  7.     stone = int(lbs) / Lbs_per_stn; // integer division
  8.     pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);
  9.     pounds = lbs;
  10. }
  11. // construct Stonewt obiect from stone,double values
  12. Stonewt::Stonewt(int stn, double lbs)
  13. {
  14.     stone = stn;
  15.     pds_left = lbs;
  16.     pounds = stn * Lbs_per_stn + lbs;
  17. }
  18. Stonewt::Stonewt() // default constructor,wt=0
  19. {
  20.     stone = pounds = pds_left = 0;
  21. }
  22. Stonewt::~Stonewt()
  23. // destructor
  24. {
  25. }
  26. // show weight in stones
  27. void Stonewt::show_stn() const
  28. {
  29.     cout
  30.         << stone << "stone," << pds_left << "pounds\n";
  31. }
  32. // show weight in pounds
  33. void Stonewt::show_lbs() const
  34. {
  35.     cout << pounds << "pounds\n";
  36. }
复制代码
对于函数



 继承两个参数的不可以不能作为转换函数

避免意外的范例转换
最新的C++实现新增了一个关键字(explicit),用来关闭这种主动特性。也就是说,可以这样声明构造函数:

但是仍可以进行显示强制范例转换

隐式转换
不发生歧义下,会进行二步转换
下面两条语句都首先将int转换为double,然后使用 Stonewt(double)构造函数。

  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; // uses constructor to initialize
  8.     Stonewt wolfe(285.7);    // same as Stonewt wolfe =285.7
  9.     Stonewt taft(21.8);
  10.     cout << "The tenor weighed ";
  11.     pavarotti.show_stn();
  12.     cout << "The detective weighed ";
  13.     wolfe.show_stn();
  14.     cout << "The President weighed ";
  15.     taft.show_lbs();
  16.     pavarotti = 265.8;
  17.     // uses constructor for conversion
  18.     taft = 325; // same as 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 weighed even more,\n";
  25.     display(422, 2);
  26.     cout << "No stone left unearned\n";
  27.     return 0;
  28. }
  29. void display(const Stonewt &st, int n)
  30. {
  31.     for (int i = 0; i < n; i++)
  32.     {
  33.         cout << "Wow!";
  34.         st.show_stn();
  35.     }
  36. }
复制代码

二步转换

转换函数


如果界说了转换函数下列就是可行的

转换函数声明

更改上述代码
  1. // stonewt.h --definition forStonewtCass
  2. #ifndef STONEWT_H_
  3. #define STONEWT_H_
  4. class Stonewt
  5. {
  6. private:
  7.     enum
  8.     {
  9.         Lbs_per_stn = 14
  10.     }; // pounds per stone
  11.     int stone;       // whole stones
  12.     double pds_left; // fractional pounds
  13.     double pounds;   // entire weight in pounds
  14. public:
  15.     Stonewt(double lbs);          // constructor for double pounds
  16.     Stonewt(int stn, double lbs); // constructor for stone,1bs
  17.     Stonewt();                    // default constructor
  18.     ~Stonewt();
  19.     void show_lbs() const;
  20.     // show weight in pounds format
  21.     void show_stn() const;
  22.     // show weight in stone format}
  23.     // conversion functions
  24.     operator int() const;
  25.     operator double() const;
  26. };
  27. #endif
复制代码
源文件
  1. #include <iostream>
  2. using std::cout;
  3. #include "stonewt.h"
  4. // construct Stonewt object from double value
  5. Stonewt::Stonewt(double lbs)
  6. {
  7.     stone = int(lbs) / Lbs_per_stn; // integer division
  8.     pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);
  9.     pounds = lbs;
  10. }
  11. // construct Stonewt obiect from stone,double values
  12. Stonewt::Stonewt(int stn, double lbs)
  13. {
  14.     stone = stn;
  15.     pds_left = lbs;
  16.     pounds = stn * Lbs_per_stn + lbs;
  17. }
  18. Stonewt::Stonewt() // default constructor,wt=0
  19. {
  20.     stone = pounds = pds_left = 0;
  21. }
  22. Stonewt::~Stonewt()
  23. // destructor
  24. {
  25. }
  26. // show weight in stones
  27. void Stonewt::show_stn() const
  28. {
  29.     cout
  30.         << stone << "stone," << pds_left << "pounds\n";
  31. }
  32. // show weight in pounds
  33. void Stonewt::show_lbs() const
  34. {
  35.     cout << pounds << "pounds\n";
  36. }
  37. Stonewt::operator double() const{    return pounds;}Stonewt::operator int() const{    return int(pounds + 0.5);}
复制代码
源文件
  1. #include <iostream>
  2. #include "stonewt.h"
  3. int main()
  4. {
  5.     using std::cout;
  6.     Stonewt poppins(9, 2.8); // 9 stone,2.8 pounds
  7.     double p_wt = poppins;   // implicit conversion
  8.     cout << "Convert to double =>";
  9.     cout << "Poppins:" << p_wt << " pounds.\n";
  10.     cout << "Convert to int =>";
  11.     cout << "Poppins:" << int(poppins) << " pounds.\n";
  12.     return 0;
  13. }
复制代码

最好使用显式转换,而避免隐式转换。关键字 explicit 不能用于转换函数,但只需用一个功能雷同的非转换函数替换该转换数即可,但仅在被显式地调用时,该函数才会执行。也就是说,可以将:


 转换函数和友元函数

重载加法的两种方式
成员函数

 友元函数

 下列合理

进行状态转换

只有友元函数答应

缘故起因:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

郭卫东

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表