0%

C++之使用类

C++之使用类……

运算符重载

1.运算符重载的基本使用

  • mytime1.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #ifndef __MYTIME1_H__
    #define __MYTIME1_H__

    #include <iostream>

    using namespace std;

    class Time
    {
    private:
    int hours;
    int minutes;
    public:
    Time();
    Time(int h, int m = 0);
    void AddMin(int m);
    void AddHr(int h);
    void Reset(int h = 0, int m = 0);
    //运算符重载的声明
    Time operator+(const Time &t) const;
    void Show() const;
    };

    #endif
  • mytime1.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #include "mytime1.h"

    Time::Time()
    {
    hours = minutes = 0;
    }

    Time::Time(int h, int m)
    {
    hours = h;
    minutes = m;
    }

    void Time::AddMin(int m)
    {
    minutes += m;
    hours += minutes / 60;
    minutes %= 60;
    }

    void Time::AddHr(int h)
    {
    hours += h;
    }

    void Time::Reset(int h, int m)
    {
    hours = h;
    minutes = m;
    }

    Time Time::operator+(const Time &t) const
    {
    Time sum;

    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + sum.minutes / 60;
    sum.minutes %= 60;

    return sum;
    }

    void Time::Show() const
    {
    cout << hours << " hours, " << minutes << " minutes." << endl;
    cout<<"---------------------------------"<<endl;
    }
  • usetime1.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #include <iostream>
    #include "mytime1.h"

    using namespace std;

    int main(void)
    {
    Time coding(2, 40);
    Time fixing(5, 55);
    Time total;
    Time Planning;

    cout << "coding time = ";
    coding.Show();

    cout << "fixing time = ";
    fixing.Show();

    //不用运算符重载的方式
    //total = coding.Sum(fixing);

    //运算符重载的常见使用方式
    total = coding + fixing;
    total.Show();

    //运算符重载的另一种使用形式
    Planning = coding.operator+(fixing);
    Planning.Show();

    return 0;
    }
  • 结果如下:

    image-20230210132912766

  • 对于Time operator+(const Time &t) const;函数,其返回值不能是引用类型Time &,因为返回类型如果是Time &,则引用的将是sum对象,但由于sum对象是局部变量,在函数结束时将被删除,因此引用将指向一个不存在的对象

2.运算符重载中遇到的问题

  • mytime2.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #ifndef __MYTIME2_H__
    #define __MYTIME2_H__

    #include <iostream>

    using namespace std;

    class Time
    {
    private:
    int hours;
    int minutes;
    public:
    Time();
    Time(int h, int m = 0);
    void AddMin(int m);
    void AddHr(int h);
    void Reset(int h = 0, int m = 0);
    Time operator+(const Time &t) const;
    Time operator-(const Time &t) const;
    Time operator*(double mult) const;
    void Show() const;
    };

    #endif
  • mytime2.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    #include "mytime2.h"

    Time::Time()
    {
    hours = minutes = 0;
    }

    Time::Time(int h, int m)
    {
    hours = h;
    minutes = m;
    }

    void Time::AddMin(int m)
    {
    minutes += m;
    hours += minutes / 60;
    minutes %= 60;
    }

    void Time::AddHr(int h)
    {
    hours += h;
    }

    void Time::Reset(int h, int m)
    {
    hours = h;
    minutes = m;
    }

    Time Time::operator+(const Time &t) const
    {
    Time sum;

    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + sum.minutes / 60;
    sum.minutes %= 60;

    return sum;
    }

    Time Time::operator-(const Time &t) const
    {
    Time diff;

    int tot1, tot2;
    tot1 = hours * 60 + minutes;
    tot2 = t.hours * 60 + t.minutes;
    diff.hours = (tot1 - tot2) / 60;
    diff.minutes = (tot1 - tot2) % 60;

    return diff;
    }

    Time Time::operator*(double mult) const
    {
    Time result;

    long totalminutes = hours*mult*60 + minutes*mult;
    result.hours = totalminutes / 60;
    result.minutes = totalminutes % 60;

    return result;
    }

    void Time::Show() const
    {
    cout << hours << " hours, " << minutes << " minutes." << endl;
    }
  • usetime2.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #include <iostream>
    #include "mytime2.h"

    using namespace std;

    int main(void)
    {
    Time coding(4, 35);
    Time fixing(2, 47);
    Time total;
    Time diff;
    Time adjusted;

    cout << "coding time = ";
    coding.Show();

    cout << "fixing time = ";
    fixing.Show();

    total = coding + fixing;
    total.Show();

    diff = coding - fixing;
    diff.Show();

    adjusted = coding * 1.5;
    adjusted.Show();

    return 0;
    }
  • 结果如下:

    image-20230213124123583

  • 对于重载运算符*,其将一个Time值与一个double值结合在一起,这限制了该运算符的使用方式,因为左侧的操作数是调用对象,故使用重载运算符时,只能写成`coding1.5,不能写成1.5*coding`,否则会报错

  • 其解决方式有使用如下的友元函数


友元函数

  • 友元函数不是成员函数,但它与成员函数有相同的访问权限

1.友元函数实现重载*运算符

  • mytime3.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #ifndef __MYTIME3_H__
    #define __MYTIME3_H__

    #include <iostream>

    using namespace std;

    class Time
    {
    private:
    int hours;
    int minutes;
    public:
    Time();
    Time(int h, int m = 0);
    void AddMin(int m);
    void AddHr(int h);
    void Reset(int h = 0, int m = 0);
    Time operator+(const Time &t) const;
    Time operator-(const Time &t) const;
    Time operator*(double mult) const;
    //友元函数的声明
    friend Time operator*(double mult, const Time &t);
    void Show() const;
    };

    #endif
  • mytime3.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    #include "mytime3.h"

    Time::Time()
    {
    hours = minutes = 0;
    }

    Time::Time(int h, int m)
    {
    hours = h;
    minutes = m;
    }

    void Time::AddMin(int m)
    {
    minutes += m;
    hours += minutes / 60;
    minutes %= 60;
    }

    void Time::AddHr(int h)
    {
    hours += h;
    }

    void Time::Reset(int h, int m)
    {
    hours = h;
    minutes = m;
    }

    Time Time::operator+(const Time &t) const
    {
    Time sum;

    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + sum.minutes / 60;
    sum.minutes %= 60;

    return sum;
    }

    Time Time::operator-(const Time &t) const
    {
    Time diff;

    int tot1, tot2;
    tot1 = hours * 60 + minutes;
    tot2 = t.hours * 60 + t.minutes;
    diff.hours = (tot1 - tot2) / 60;
    diff.minutes = (tot1 - tot2) % 60;

    return diff;
    }

    Time Time::operator*(double mult) const
    {
    Time result;

    long totalminutes = hours*mult*60 + minutes*mult;
    result.hours = totalminutes / 60;
    result.minutes = totalminutes % 60;

    return result;
    }

    void Time::Show() const
    {
    cout << hours << " hours, " << minutes << " minutes." << endl;
    }

    //友元函数的定义
    Time operator*(double mult, const Time &t)
    {
    Time result;

    long totalminutes = t.hours*mult*60 + t.minutes*mult;
    result.hours = totalminutes / 60;
    result.minutes = totalminutes % 60;

    return result;
    }
  • usetime3.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    #include <iostream>
    #include "mytime3.h"

    using namespace std;

    int main(void)
    {
    Time coding(4, 35);
    Time fixing(2, 47);
    Time total;
    Time Planning;
    Time diff;
    Time adjusted;

    cout << "coding time = ";
    coding.Show();

    cout << "fixing time = ";
    fixing.Show();

    total = coding + fixing;
    total.Show();

    diff = coding - fixing;
    diff.Show();

    adjusted = coding * 1.5;
    adjusted.Show();

    adjusted = 1.5 * coding;
    adjusted.Show();

    return 0;
    }
  • 结果如下:

    image-20230213130105898

2.友元函数实现重载<<运算符

  • mytime4.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #ifndef __MYTIME4_H__
    #define __MYTIME4_H__

    #include <iostream>

    using namespace std;

    class Time
    {
    private:
    int hours;
    int minutes;
    public:
    Time();
    Time(int h, int m = 0);
    void AddMin(int m);
    void AddHr(int h);
    void Reset(int h = 0, int m = 0);
    Time operator+(const Time &t) const;
    Time operator-(const Time &t) const;
    Time operator*(double mult) const;
    friend Time operator*(double mult, const Time &t);
    //利用友元函数重载运算符<<,实现输出显示
    friend ostream &operator<<(ostream &os, const Time &t);
    // void Show() const;
    };

    #endif
  • mytime4.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    #include "mytime4.h"

    Time::Time()
    {
    hours = minutes = 0;
    }

    Time::Time(int h, int m)
    {
    hours = h;
    minutes = m;
    }

    void Time::AddMin(int m)
    {
    minutes += m;
    hours += minutes / 60;
    minutes %= 60;
    }

    void Time::AddHr(int h)
    {
    hours += h;
    }

    void Time::Reset(int h, int m)
    {
    hours = h;
    minutes = m;
    }

    Time Time::operator+(const Time &t) const
    {
    Time sum;

    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + sum.minutes / 60;
    sum.minutes %= 60;

    return sum;
    }

    Time Time::operator-(const Time &t) const
    {
    Time diff;

    int tot1, tot2;
    tot1 = hours * 60 + minutes;
    tot2 = t.hours * 60 + t.minutes;
    diff.hours = (tot1 - tot2) / 60;
    diff.minutes = (tot1 - tot2) % 60;

    return diff;
    }

    Time Time::operator*(double mult) const
    {
    Time result;

    long totalminutes = hours*mult*60 + minutes*mult;
    result.hours = totalminutes / 60;
    result.minutes = totalminutes % 60;

    return result;
    }
    /*
    void Time::Show() const
    {
    cout << hours << " hours, " << minutes << " minutes." << endl;
    }
    */
    Time operator*(double mult, const Time &t)
    {
    Time result;

    long totalminutes = t.hours*mult*60 + t.minutes*mult;
    result.hours = totalminutes / 60;
    result.minutes = totalminutes % 60;

    return result;
    }

    ostream &operator<<(ostream &os, const Time &t)
    {
    os << t.hours << " hours, " << t.minutes << " minutes." << endl;
    return os;
    }
  • usetime4.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #include <iostream>
    #include "mytime4.h"

    using namespace std;

    int main(void)
    {
    Time coding(4, 35);
    Time fixing(2, 47);
    Time total;
    Time Planning;
    Time diff;
    Time adjusted;

    cout << "coding time = ";
    // coding.Show();
    cout << coding;

    cout << "fixing time = ";
    // fixing.Show();
    cout << fixing;

    total = coding + fixing;
    // total.Show();
    cout << total;

    diff = coding - fixing;
    // diff.Show();
    cout << diff;
    adjusted = coding * 1.5;
    // adjusted.Show();
    cout << adjusted;

    adjusted = 1.5 * coding;
    // adjusted.Show();
    cout << adjusted;

    cout << "************************" << endl;
    cout << coding << fixing;

    return 0;
    }
  • 结果如下:

    image-20230213132741698


矢量类

  • vector.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    #ifndef __VECTOR_H__
    #define __VECTOR_H__

    #include <iostream>

    using namespace std;

    namespace VECTOR
    {
    class Vector
    {
    public:
    enum Mode{RECT, POL};
    private:
    //直角坐标x,y
    double x;
    double y;
    //极坐标的模长mag以及角度ang
    double mag;
    double ang;
    //模式:是直角坐标还是极坐标
    Mode mode;
    //计算极坐标的模值和角度
    void set_mag();
    void set_ang();
    //计算直角坐标的x与y值
    void set_x();
    void set_y();
    public:
    //默认构造函数
    Vector();
    //用户自定义构造函数:初始化直角坐标与极坐标
    Vector(double n1, double n2, Mode form = RECT);
    //重置直角坐标与极坐标
    void reset(double n1, double n2, Mode form = RECT);
    //返回各个成员变量
    double xval() const{return x;}
    double yval() const{return y;}
    double magval() const{return mag;}
    double angval() const{return ang;}
    //设置坐标系模式
    void polar_mode();
    void rect_mode();
    //成员函数实现坐标计算
    Vector operator+(const Vector &b) const;
    Vector operator-(const Vector &b) const;
    Vector operator-() const;//这里的-代表取反
    Vector operator*(double n) const;
    //友元函数实现重载*与输出<<
    friend Vector operator*(double n, const Vector &a);
    friend ostream &operator<<(ostream &os, const Vector &v);
    };
    }

    #endif
  • vector.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    #include "vector.h"
    #include <cmath>

    namespace VECTOR
    {
    const double Rad_to_deg = 45.0 / atan(1.0);

    void Vector::set_mag()
    {
    mag = sqrt(x*x + y*y);
    }
    void Vector::set_ang()
    {
    if(x == 0.0 && y == 0.0)
    ang = 0.0;
    else
    ang = atan2(y, x);
    }

    void Vector::set_x()
    {
    x = mag * cos(ang);
    }
    void Vector::set_y()
    {
    y = mag * sin(ang);
    }

    Vector::Vector()
    {
    x = y = mag = ang = 0.0;
    mode = RECT;
    }
    Vector::Vector(double n1, double n2, Mode form)
    {
    mode = form;
    if(form == RECT)
    {
    x = n1;
    y = n2;
    set_mag();
    set_ang();
    }
    else if(form == POL)
    {
    mag = n1;
    ang = n2 / Rad_to_deg;
    set_x();
    set_y();
    }
    else
    {
    cout << "Error" << endl;
    x = y = mag = ang = 0.0;
    mode = RECT;
    }
    }

    void Vector::reset(double n1, double n2, Mode form)
    {
    mode = form;
    if(form == RECT)
    {
    x = n1;
    y = n2;
    set_mag();
    set_ang();
    }
    else if(form == POL)
    {
    mag = n1;
    ang = n2 / Rad_to_deg;
    set_x();
    set_y();
    }
    else
    {
    cout << "Error" << endl;
    x = y = mag = ang = 0.0;
    mode = RECT;
    }
    }

    void Vector::polar_mode()
    {
    mode = POL;
    }
    void Vector::rect_mode()
    {
    mode = RECT;
    }

    Vector Vector::operator+(const Vector &b) const
    {
    return Vector(x + b.x, y + b.y);//巧妙利用自定义构造函数返回计算后的Vector类
    }
    Vector Vector::operator-(const Vector &b) const
    {
    return Vector(x - b.x, y - b.y);
    }
    Vector Vector::operator-() const
    {
    return Vector(-x, -y);
    }
    Vector Vector::operator*(double n) const
    {
    return Vector(n*x, n*y);
    }

    Vector operator*(double n, const Vector &a)
    {
    return a * n;//巧妙利用重载运算符*实现a*n
    }
    ostream &operator<<(ostream &os, const Vector &v)
    {
    if(v.mode == Vector::RECT)//在类声明外使用public内容都需要加Vector
    os << "x, y = " << v.x << ", " << v.y << endl;
    else if(v.mode == Vector::POL)
    os << "mag, ang = " << v.mag << ", " << v.ang << endl;
    else
    os << "Invalid mode" << endl;

    return os;
    }
    }
  • main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    #include "vector.h"

    using namespace std;
    using namespace VECTOR;

    int main(void)
    {
    double target;
    double dstep;
    Vector result(0.0, 0.0);
    double direction;
    Vector step;
    unsigned long steps = 0;

    //随机数种子
    srand(time(NULL));

    cout << "Enter target distance(q to quit): ";
    while(cin >> target)
    {
    cout << "Enter the step lenght: ";
    if(!(cin >> dstep))
    break;

    while(result.magval() < target)
    {
    direction = rand() % 360;
    step.reset(dstep, direction, Vector::POL);
    result = result + step;
    steps++;
    }

    cout << "After " << steps << " steps, the subject has the following location:\n";
    cout << result;
    result.polar_mode();
    cout << result;

    cout << endl;

    steps = 0;
    result.reset(0.0, 0.0);
    cout << "Enter target distance(q to quit): ";
    }
    cout << "Bye" << endl;

    return 0;
    }
  • 结果如下:

    屏幕截图_20230214_131742


类的自动转换与强制类型转换

1.类的自动类型转换

  • 定义类对象时使用=,会自动调用相匹配的构造函数实现自动类型转换,例如:

    1
    Stonewt incognito = 275;//就相当于是Stonewt incognito(275); Stonewt incognito = Stonewt(275);
  • 可使用explicit禁止自动类型转换,例如:

    1
    explicit Stonewt(double lbs);
  • stonewt.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #ifndef __STONEWT_H__
    #define __STONEWT_H__

    #include <iostream>

    using namespace std;

    class Stonewt
    {
    private:
    enum{Lbs_per_stn = 14};
    int stone;
    double pds_left;
    double pounds;
    public:
    //使用explicit禁止自动类型转换
    //explicit Stonewt(double lbs);
    Stonewt(double lbs);
    Stonewt(int stn, double lbs);
    Stonewt();
    void show_lbs() const;
    void show_stn() const;
    };

    #endif
  • stonewt.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #include "stonewt.h"

    Stonewt::Stonewt(double lbs)
    {
    stone = (int)lbs / Lbs_per_stn;
    pds_left = (int)lbs % Lbs_per_stn + lbs - (int)lbs;
    pounds = lbs;
    }

    Stonewt::Stonewt(int stn, double lbs)
    {
    stone = stn;
    pds_left = lbs;
    pounds = stn * Lbs_per_stn + lbs;
    }

    Stonewt::Stonewt()
    {
    stone = pds_left = pounds = 0;
    }

    void Stonewt::show_stn() const
    {
    cout << stone << " stone, " << pds_left << " pounds." << endl;
    }

    void Stonewt::show_lbs() const
    {
    cout << pounds << " pounds." << endl;
    }
  • stone.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #include <iostream>
    #include "stonewt.h"

    using namespace std;

    int main(void)
    {
    Stonewt incognito = 275;//Stonewt incognito(275); Stonewt incognito = Stonewt(275);
    Stonewt wolfe(285.7); //Stonewt(double );
    Stonewt taft(21, 8);

    incognito.show_stn();
    wolfe.show_stn();
    taft.show_lbs();

    cout << "-------------------------" << endl;
    incognito = 276.8;
    taft = 325;
    incognito.show_stn();
    taft.show_lbs();

    return 0;
    }
  • 结果如下:

    image-20230215142637177

2.类的强制类型转换

  • 转换函数:转换函数是类成员函数,没有返回类型和参数,名为operator typeName(),其中typeName是对象将被转换成的类型

  • 在转换函数的声明前加explicit可防止隐式转换,而只允许显示转换

  • stonewt1.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #ifndef __STONEWT_H__
    #define __STONEWT_H__

    #include <iostream>

    using namespace std;

    class Stonewt
    {
    private:
    enum{Lbs_per_stn = 14};
    int stone;
    double pds_left;
    double pounds;
    public:
    //explicit Stonewt(double lbs);
    Stonewt(double lbs);
    Stonewt(int stn, double lbs);
    Stonewt();
    void show_lbs() const;
    void show_stn() const;
    //转换函数
    operator double() const;
    operator int() const;
    };

    #endif
  • stonewt1.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #include "stonewt1.h"

    Stonewt::Stonewt(double lbs)
    {
    stone = (int)lbs / Lbs_per_stn;
    pds_left = (int)lbs % Lbs_per_stn + lbs - (int)lbs;
    pounds = lbs;
    }

    Stonewt::Stonewt(int stn, double lbs)
    {
    stone = stn;
    pds_left = lbs;
    pounds = stn * Lbs_per_stn + lbs;
    }

    Stonewt::Stonewt()
    {
    stone = pds_left = pounds = 0;
    }

    void Stonewt::show_stn() const
    {
    cout << stone << " stone, " << pds_left << " pounds." << endl;
    }

    void Stonewt::show_lbs() const
    {
    cout << pounds << " pounds." << endl;
    }

    Stonewt::operator int() const
    {
    return (int)(pounds + 0.5);
    }

    Stonewt::operator double() const
    {
    return pounds;
    }
  • stone1.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #include <iostream>
    #include "stonewt1.h"

    using namespace std;

    int main(void)
    {
    Stonewt poppins(9, 2.8);

    //隐式调用转换函数:operator double() const
    double p_wt = poppins;
    cout << "poppins = " << p_wt << " pounds." << endl;

    //隐式调用转换函数:operator int() const;
    int weight = poppins;
    cout << "poppins = " << weight << " pounds." << endl;

    //显示调用转换函数:此处若不使用显示调用则会报错,因为两个转换函数都满足条件
    cout << "poppins = " << int(poppins) << " pounds." << endl;
    cout << "poppins = " << double(poppins) << " pounds." << endl;

    return 0;
    }
  • 结果如下:

    屏幕截图_20230216_211341


练习

1.将矢量类中的结果输出至文本文件

  • vectorFile.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    #include "vector.h"
    #include <fstream>

    using namespace std;
    using namespace VECTOR;

    int main(void)
    {
    double target;
    double dstep;
    Vector result(0.0, 0.0);
    double direction;
    Vector step;
    unsigned long steps = 0;

    //输入文件对象
    ofstream fout;
    fout.open("randwalk.txt");

    srand(time(NULL));

    cout << "Enter target distance(q to quit): ";
    while(cin >> target)
    {
    cout << "Enter the step lenght: ";
    if(!(cin >> dstep))
    break;

    //在文件中输出目标距离和每步的长度
    fout << "Target distance: " << target << ", step size: " << dstep << endl;

    while(result.magval() < target)
    {
    //在文件中输出每一步的位置
    fout << steps << ": (x, y) = " << result << endl;
    direction = rand() % 360;
    step.reset(dstep, direction, Vector::POL);
    result = result + step;
    steps++;
    }

    cout << "After " << steps << " steps, the subject has the following location:\n";
    cout << result;

    //在文件中输出最终需要多少步以及最终的位置
    fout << "After " << steps << " steps, the subject has the following location:\n";
    fout << result;

    result.polar_mode();
    cout << result;
    fout << result;

    //在文件中显示平均每一步走多远
    fout << "Average outward distance per step = " << result.magval() / steps << endl;

    cout << endl;
    fout << "------------------------------------------------------\n"<<endl;

    steps = 0;
    result.reset(0.0, 0.0);
    cout << "Enter target distance(q to quit): ";
    }
    cout << "Bye" << endl;
    fout.close();
    return 0;
    }

    结果如下:

    屏幕截图_20230218_163055

    image-20230218163421983

2.类实现有关复数运算

  • 输入输出流一定要使用友元函数重载,若直接重载那运算符左侧一定要是类的对象,所以只能使用友元函数重载运算符

  • complex0.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #ifndef __COMPLEX_0_H__
    #define __COMPLEX_0_H__

    #include <iostream>

    using namespace std;

    class complex
    {
    private:
    double real;
    double imaginary;
    public:
    complex();
    complex(double r, double i);
    complex operator+(const complex &c) const;
    complex operator-(const complex &c) const;
    complex operator*(const complex &c) const;
    complex operator~() const;

    friend complex operator*(double x, const complex &c);
    friend istream &operator>>(istream &is, complex &c);
    friend ostream &operator<<(ostream &os, const complex &c);
    };

    #endif
  • complex0.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    #include "complex0.h"

    complex::complex()
    {
    real = imaginary = 0.0;
    }

    complex::complex(double r, double i)
    {
    real = r;
    imaginary = i;
    }

    complex complex::operator+(const complex &c) const
    {
    return complex(real+c.real, imaginary+c.imaginary);
    }

    complex complex::operator-(const complex &c) const
    {
    return complex(real-c.real, imaginary-c.imaginary);
    }

    complex complex::operator*(const complex &c) const
    {
    return complex(real*c.real - imaginary*c.imaginary, real*c.imaginary + imaginary*c.real);
    }

    complex complex::operator~() const
    {
    return complex(real, -imaginary);
    }

    complex operator*(double x, const complex &c)
    {
    return complex(x*c.real, x*c.imaginary);
    }

    //输入符重载
    istream &operator>>(istream &is, complex &c)
    {
    is >> c.real >> c.imaginary;
    return is;
    }

    ostream &operator<<(ostream &os, const complex &c)
    {
    os << "real = " << c.real << ", imaginary = " << c.imaginary << endl;
    return os;
    }
  • main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #include <iostream>
    #include "complex0.h"

    using namespace std;

    int main(void)
    {
    complex a(3.0, 4.0);
    complex c;
    cout << "Enter a complex number (q to quit): \n";

    while(cin >> c)
    {
    cout << "c is " << c << endl;
    cout << "complex conjugate is " << ~c << endl;
    cout << "a is " << a << endl;
    cout << "a + c is " << a + c << endl;
    cout << "a - c is " << a - c << endl;
    cout << "a * c is " << a * c << endl;
    cout << "2 * c is " << 2 * c << endl;
    cout << "Enter a complex number (q to quit): \n";
    }
    cout << "Done\n";

    return 0;
    }
  • 结果如下:

    屏幕截图_20230219_232832

3.类对象数组的初始化与比较

  • 类对象数组的初始化:通过类的自动类型转换或构造函数初始化
1
Stonewt stone_arr[SIZE] = {275, Stonewt(285.7), Stonewt(21, 8)};
  • stonewt.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #ifndef __STONEWT_H__
    #define __STONEWT_H__

    #include <iostream>

    using namespace std;

    class Stonewt
    {
    private:
    enum{Lbs_per_stn = 14};
    int stone;
    double pds_left;
    double pounds;
    public:
    Stonewt(double lbs);
    Stonewt(int stn, double lbs);
    Stonewt();

    bool operator<(const Stonewt &s) const;
    bool operator<=(const Stonewt &s) const;
    bool operator>(const Stonewt &s) const;
    bool operator>=(const Stonewt &s) const;
    bool operator==(const Stonewt &s) const;
    bool operator!=(const Stonewt &s) const;

    void show_lbs() const;
    void show_stn() const;
    };

    #endif
  • stonewt.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #include "stonewt.h"

    Stonewt::Stonewt(double lbs)
    {
    stone = (int)lbs / Lbs_per_stn;
    pds_left = (int)lbs % Lbs_per_stn + lbs - (int)lbs;
    pounds = lbs;
    }

    Stonewt::Stonewt(int stn, double lbs)
    {
    stone = stn;
    pds_left = lbs;
    pounds = stn * Lbs_per_stn + lbs;
    }

    Stonewt::Stonewt()
    {
    stone = pds_left = pounds = 0;
    }

    bool Stonewt::operator<(const Stonewt &s) const
    {
    return pounds < s.pounds;
    }

    bool Stonewt::operator<=(const Stonewt &s) const
    {
    return pounds <= s.pounds;
    }

    bool Stonewt::operator>(const Stonewt &s) const
    {
    return pounds > s.pounds;
    }

    bool Stonewt::operator>=(const Stonewt &s) const
    {
    return pounds >= s.pounds;
    }

    bool Stonewt::operator==(const Stonewt &s) const
    {
    return pounds == s.pounds;
    }

    bool Stonewt::operator!=(const Stonewt &s) const
    {
    return pounds != s.pounds;
    }

    void Stonewt::show_stn() const
    {
    cout << stone << " stone, " << pds_left << " pounds." << endl;
    }

    void Stonewt::show_lbs() const
    {
    cout << pounds << " pounds." << endl;
    }
  • stone.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #include <iostream>
    #include "stonewt.h"

    using namespace std;

    const int SIZE = 6;

    int main(void)
    {
    //类对象数组的赋值
    Stonewt stone_arr[SIZE] = {275, Stonewt(285.7), Stonewt(21, 8)};
    double input;
    Stonewt max = stone_arr[0];
    Stonewt min = stone_arr[0];
    Stonewt eleven = Stonewt(11, 0.0);
    unsigned int count = 0;

    for(int i = 3; i < SIZE; i++)
    {
    cout << "Enter number " << i + 1 << " element.(in pounds)" << endl;
    cin >> input;
    stone_arr[i] = Stonewt(input);
    }

    for(int i = 0; i < SIZE; i++)
    {
    max = max > stone_arr[i] ? max : stone_arr[i];
    min = min < stone_arr[i] ? min : stone_arr[i];
    if(stone_arr[i] > eleven)
    count++;
    }

    cout << "The max weigth: ";
    max.show_lbs();
    cout << "The min weight: ";
    min.show_lbs();
    cout << count << " objects are heavier than eleven" << endl;

    return 0;
    }
  • 结果如下:

    屏幕截图_20230219_234404

欢迎来到ssy的世界