DSA icon indicating copy to clipboard operation
DSA copied to clipboard

第10章 对象和类

Open lefex opened this issue 6 years ago • 0 comments

/**
 第10章 对象和类
 过程性编程和面向对象编程
 类概念
 如何定义和实现类
 公有访问和私有访问
 类方法(类成员函数)
 创建和使用对象
 类的构造函数和析构函数
 const成员函数;
 this指针;
 创建对象数组;
 类作用域;
 抽象数据类型;
 */

/**
 * 定义一个股票类,通常C++中回把接口(类定义)放到头文件中,
 * 并将实现放到源文件中。
 */
// 类定义使用关键字 class
class Stock
{
/**
 控制对成员的访问,private为私有的,company,shares等都是Stock的私有
 数据成员,如果使用非成员函数访问这些私有成员将报错。
 */
private:
    std::string company;
    long shares;
    double share_val;
    double total_val;
    void set_tot() { total_val = shares * share_val; }
public:
    /**
     默认函数,当为一个类提供了构造函数,必须提供一个默认构造函数
     隐式调用默认构造函数
     Stock stock;
     显式调用默认构造函数
     Stock stock = Stock();
     */
    Stock();
    /**
     构造函数,带有默认参数 n(shares)为0,pr(share_val)为 0.0
     1.默认参数可以省略
     Stock stock = Stock("Lefex");
     2.传递默认参数
     Stock stock4 = Stock("Lefex4", 10, 20);
     3.使用 new 关键字创建的对象需要使用 delete 移除,否则不会自动释放
     Stock *stock5 = new Stock();
     delete stock5;
     */
    Stock(const std::string & co, long n = 0, double pr = 0.0);
    /**
     析构函数,对象被销毁后将自动被调用,它主要用来做清理工作,比如通过new来
     分配内存,需要使用delete来释放内存。通常会在析构函数中使用delete来释放
     对像中的内存空间。
     */
    ~Stock();
    /**
     成员函数
     */
    void buy(long num, double price);
    void sell(long num, double price);
    void update(double price);
    void show();
    
    /**
     这个函数用来找出最大的Stock,改函数隐式地访问一个对象,
     而显式地访问另一个对象,并返回一个对象的引用。const说明:
     1、括号中的 const 表明该函数不会修改被显式访问的对象
     2、括号后的 const 表明该函数不会修改被隐式访问的对象
     3、由于返回的是两个 const 对象之一的引用,因此返回类型也为 const 类型
     */
    const Stock & topval(const Stock & s) const;
};

#endif /* LEFClass10_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