C++PrimerPlus学习之使用类

版权声明:转载之前请说你是博主的粉丝哦。 https://blog.csdn.net/qq_34921856/article/details/83622919

运算符重载

  • 一个例子

    //mytime0.h
    #ifndef MYTIME0_H_INCLUDED
    #define MYTIME0_H_INCLUDED
    
    class Time
    {
    private:
        int hours;
        int minutes;
    public:
        Time(){hours=minutes=0;}
        Time(int h,int m=0){hours=h+m/60;minutes=m%60;}
        void show()const{std::cout<<hours<<" hours, "<<minutes<<" minutes\n";}
    
        //operator
        Time operator+(const Time &t)const//返回类型不要使用引用
        {
            Time sum;
            sum.minutes=minutes+t.minutes;
            sum.hours=hours+t.hours;
            sum.hours=sum.hours+sum.minutes/60;
            sum.minutes%=60;
            return sum;
        }
        Time operator*(const int &v)const//另一种重载方式,非同类型重载
        {
            return Time(hours*v,minutes*v);
        }
    };
    
    #endif // MYTIME0_H_INCLUDED
    
    
    //main.cpp
    #include<bits/stdc++.h>
    #include"mytime0.h"
    using namespace std;
    int main()
    {
        Time thetime=Time(12,15);
        thetime.show();
        Time lxttime=Time(11,5);
        thetime=thetime+lxttime;
        thetime.show();
    }
    
  • 重载限制

    • 重载后的运算符必须至少一个操作数是用户定义的类型
    • 使用运算符重载不能违反运算符原来的句法规则 – 操作数的个数 和 优先级
    • 不能创建新运算符
    • 有些运算符不能重载 – 可百度一下
    • 有些运算符只能通过成员函数重载 – 而不能通过非成员函数重载
      • = ,() , [] , ->

友元函数

  • 重载遗留下的问题
    thetime=thetime*2;//allowed
    thetime=2*thetime;//not allowed
    

我们只能使用非成员函数解决改问题,但常规非成员函数不能访问私有成员,只有一类特殊的非成员函数可以访问类的私有成员-友元函数。

  • 声明

    • 原型放在类中,但不是类成员函数,不用使用::
    • 前加friend,定义不用加,可访问类的私有成员。
      friend Time operator*(double m,const Time &t);
      
  • 定义

    • 不用加friend
    • 不用加 类名::
  • 常见的友元函数

    ostream & operator<<(ostream & os,const c_name &obj)
    {
      os << ...;
      return os;
    }
    
  • 改进后的Time类

    #ifndef MYTIME0_H_INCLUDED
    #define MYTIME0_H_INCLUDED
    #include<iostream>
    class Time
    {
    private:
        int hours;
        int minutes;
    public:
        Time(){hours=minutes=0;}
        Time(int h,int m=0){hours=h+m/60;minutes=m%60;}
        void show()const{std::cout<<hours<<" hours, "<<minutes<<" minutes\n";}
    
        //operator
        Time operator+(const Time &t)const//返回类型不要使用引用
        {
            Time sum;
            sum.minutes=minutes+t.minutes;
            sum.hours=hours+t.hours;
            sum.hours=sum.hours+sum.minutes/60;
            sum.minutes%=60;
            return sum;
        }
        Time operator*(const int &v)const//另一种重载方式,非同类型重载
        {
            return Time(hours*v,minutes*v);
        }
        friend Time operator*(int v,const Time &t)
        {
            return t*v;
        }
        friend std::ostream &operator<<(std::ostream &os,const Time &t)
        {
            os<<t.hours<<" hours, "<<t.minutes<<" minutes\n";
            return os;
        }
    };
    #endif // MYTIME0_H_INCLUDED
    //main.cpp 
    #include<bits/stdc++.h>
    #include"mytime0.h"
    using namespace std;
    int main()
    {
        Time thetime=Time(12,15);
        thetime=2*thetime;//allowed
        cout<<thetime<<endl;
        return 0;
    }
    
    

类的转换

  • 其他类型转换成类
    • 只含有一个参数的构造函数可以作为转换函数,进行自动(隐式转换)
    • 构造时应避免二义性。
      Time(int h);//构造函数
      Time mytime;
      mytime=16;
      
    • explicit关键字
      • 有时候不需要这种自动特性,声明时使用该关键字即可。
        explicit Time(int h)
        Time mytime=16;//not allowed
        mytime=Time(16);//allowed
        mytime=(Time)16;//allowed
        
  • 该类转换成其他类型
    • 应避免二义性
    • 有时候会出现错误,故在声明转换函数时加上explicit,并使用显式转换。
    • 或者另外声明一个成员函数来进行类型转换。
    • 声明
      explicit operator int() const
      
    • 定义
      Time::explicit operator int()const
      {
        return hours;
      }
      

猜你喜欢

转载自blog.csdn.net/qq_34921856/article/details/83622919