DSA icon indicating copy to clipboard operation
DSA copied to clipboard

第11章 使用类

Open lefex opened this issue 6 years ago • 0 comments

/**
 第11章 使用类
 运算符重载
 友元函数
 重载<<运算符,以便于输出
 
 ========================
 状态成员
 使用rand()生成随机值;
 类的自动转换和强制转换;主要介绍了对象直接的类型转换,比如可以把一个double类型的变量转换成对象;
 类转换函数;
 */


#ifndef LEFClass11_hpp
#define LEFClass11_hpp

#include <stdio.h>
#include <iostream>

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 Sum(const Time & t) const;
    /**
     重载运算符,语法为:
     operator op(参数列表)
     只能重载已经存在的运算符,比如+、-、*,而不能重载@
     Time coding(2, 40);
     Time fixing(5, 55);
     Time sum;
     也可以通过 sum = coding.operator+(fixing); 这样的方式调用;
     【规则】:
     1、必须由一个操作数是自定义类型;
     2、使用运算符时不能违反运算符原来的句法规则,也不能修改运算符的优先级,比如不能 %x;
     3、不能创建新的运算符;
     4、不能重载特点的运算符,比如:sizeof
     */
    Time operator+(const Time & t) const;
    /**
     使用非成员函数重载运算符需要两个参数,而使用成员函数重载需要一个参数,因为
     其中一个参数可以通过 this 访问。
     【使用友元函数进行重载】
     friend Time operator+(const Time & t1, const Time & t2);
     */

    Time operator-(const Time & t) const;
    // time * 1.2
    Time operator*(double n) const;
    
    /**
     友元:
     提供了一种访问私有成员的方法,我们都知道访问私有成员只能通过成员函数访问。典型的是
     非成员函数无法访问私有变量。有一种特殊的非成员函数可以访问私有变量,它们就是【友元函数】。
     1.2 * time
     */
    friend Time operator*(double m, const Time & t);
    /**
     重载符号 <<:
     cout << adjust << ", the end";
     */
    friend std::ostream & operator<<(std::ostream & os, const Time & t);

    void Show() const;
};

/**
 定义一个向量
 */
namespace VECTOR {
    class Vector {
    public:
        // 定义枚举值,在类中可以作为常量定义
        enum Mode {RECT, POL};
    private:
        double x;
        double y;
        double mag;
        double ang;
        Mode mode;
        void set_mag();
        void set_ang();
        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);
        ~Vector();
        /**
         下面4个函数由于在类声明中定义的,所以自动成为了内联函数
         */
        double xval() { return x;};
        double yval() { return y;};
        double magval() { return mag;};
        double angval() { 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 std::ostream & operator<<(std::ostream & os, const Vector & v);
    };
}

#endif /* LEFClass11_hpp */

#include "LEFClass11.hpp"
#include <iostream>

Time::Time() {
    hours = 0;
    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::Sum(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 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 = t.minutes + 60 * t.hours;
    tot2 = minutes + 60 * hours;
    diff.minutes = (tot2 - tot1) % 60;
    diff.hours = (tot2 - tot1) / 60;
    return diff;
}

Time Time::operator*(double n) const {
    Time result;
    int totalMin = hours * n * 60 + minutes * n;
    result.hours = totalMin / 60;
    result.minutes = totalMin % 60;
    return result;
}

Time operator*(double m, const Time & t) {
    Time result;
    // 因为是友元函数,可以访问私有成员
    int totalMin = t.hours * m * 60 + t.minutes * m;
    result.hours = totalMin / 60;
    result.minutes = totalMin % 60;
    return result;
}

std::ostream & operator<<(std::ostream & os, const Time & t) {
    os << t.hours << " hours:," << t.minutes << " sminutes";
    // 返回 os 是为了可以使用 cout << adjust << ", the end";
    return os;
}

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

#include <cmath>
using std:: sqrt;
using std:: sin;
using std:: cos;
using std:: atan;
using std:: atan2;
using std:: cout;

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 {
            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 {
            x = y = mag = ang = 0.0;
            mode = RECT;
        }
    }
    
    Vector::~Vector() {
        
    }
    
    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::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 {
        // 仅支持 vector * 1.2 这样的形式,不支持 1.2 * vector 这样的形式
        return Vector(n * x, n * y);
    }
    
    Vector operator*(double n, const Vector & a) {
        // 直接调用已经重载的函数,operator*
        return a * n;
    }
    
    std::ostream & operator<<(std::ostream & os, const Vector & v) {
        if (v.mode == Vector::RECT) {
            os << "RECT";
        } else if (v.mode == Vector::POL) {
            os << "POL";
        } else {
            os << "Mode is error";
        }
        return os;
    }
}


lefex avatar Mar 09 '19 05:03 lefex