c++ 第十一章 使用类

//c++ 第十一章 使用类

注:参考 c++ primer plus

一.运算符重载

1. 带有运算符重载的类声明

class Time
{
private: 
    int hours;
    int minutes;
public:
    Time();
    explicit Time(int h,int m = 0);//explicit 关闭隐式转换 Time time = 10;无效的
    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;//-运算符重载
    void show()const;
};

2. ‘+号’运算符重载函数定义

Time Time::operator+(const Time &t)const{
    Time sum;
    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + minutes/60;
    sum.minutes = sum.minutes%60;
    return sum;
}

3. 运算符重载用法

Time time(5,25); Time time1(3,59);//运算符重载用法 与 普通用法一样。
time = time + time1;

二.友元函数

1. 带友元函数的类声明

class Time
{
private: 
    ...
public:
    ...
    Time operator*(const float m)const;
    friend Time operator*(const float m,const Time &t); //友元函数定义
};

延伸://为什么需要友元函数?
由于 Time operator*(const float m)const; 定义中m 不是类。
所以 Time time = time * 0.25 -> time = time.operator*(0.25);
不能写成 Time time = 0.25 * time;

//该友元原型意味着以下两点:
(1) 虽然operator*()函数是在类声明中声明的,但他不是成员函数,因此不能使用成员操作符来调用。
(2) 虽然operator*()不是成员函数,但它具有与成员函数相同的权限。

2. 友元函数定义时不能加类限定符 Time::

Time /*Time::*/operator*(const float m,const Time &t){
    Time result;
    long totalminutes = t.hours*m*60 + m*t.minutes;
    result.hours = totalminutes/60;
    result.minutes = totalminutes%60;
    return result;
    //实际上还可以写为:
    return t*m;//调用了Time operator*(const float m)const;
}   

3. 用法

Time time = time * 0.25;//实际调用Time operator*(const float m)const;
Time time = 0.25 * time;//实际调用friend Time operator*(const float m,const Time &t);

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

//定义
class Time{
    ...
    friend std::ostream & operator<<(std::ostream & os,const Time &t);//为了让用户定义的类,也能像int 那样用cout输出。
}
//原型  一般按照这种模式定义
std::ostream & operator<<(std::ostream & os,const Time &t){
    os << "The time is " << t.hours << "." << t.minutes << std::endl;
    return os;
}

5. 什么时候用友元函数

(1)重载操作符时,有参数为非成员参数。一般来说,非成员函数应为友元函数,这样才能访问类的私有数据。
(2)非成员版本的重载操作符函数所需的形参数目与操作数数目相同,而成员版本所需的成员函数少一个,因为其中一个是被隐式传递的调用对象。

三.强制类型转换

1. 类定义

namespace Vector {
    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();
        ~Stonewt();
        void show_lbs()const;
        void show_stn()const;
        friend std::ostream & operator<<(std::ostream & os,Stonewt & s);
        operator int()const;    //强制转换为int型函数
        operator double()const; //强制转换为double型函数
        //可以替换为 Ston_to_Int(){return (pounds + 0.5);};
        //用法  int plb = poppins.Ston_to_Int();
    };
}

2. 转换函数原型

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

    Stonewt::operator double()const{
        return pounds;
    }

3. 使用方法

Vector::Stonewt poppins(9,2.8);
double p_wt = poppins;          //poppins被强制转换成了double;
long gone = (double)poppins;    //首先强制转换为double,再由double转换为long
cout << "poppins = " << poppins << endl;
cout << "p_wt = " << p_wt << endl;

猜你喜欢

转载自blog.csdn.net/a185531353/article/details/78573284