• 使用类2(七)


          在前面我们学习了关于类的一些基本使用,下面我们更深入的学习使用类。这里包含了下面几个内容:

      1:操作符重载

      2:友员

      3:类的转换

    操作符重载:使我们对类型使用+、-等常用操作符。要重载操作符,需使用称为运算符函数的特殊函数,它的形式如下:

      operator op(argument-list) ;                               op 可以是+、-、*、/等操作符,argument-list 是参数列表

    下面创建一个两个时间相加的+操作符:

    #include<iostream>
    
    using namespace std ;
    
    class Time{
    private :
            int hour , minute , second ;
    public :
            Time(int hour , int minute , int second) ;
            Time() {}     //默认构造函数
            Time operator+(const Time &t) const ;
            void show()const ;
    } ;
    
    int main(){
            Time t1(3 , 20 , 30) ;
            Time t2(4 , 30 , 10) ;
    
            cout << "t1 : 
    " ;
             t1.show() ;
            cout << "t2 : 
    " ;
             t2.show() ;
    
            Time t3 = t1 + t2 ;
    cout << "t3 : " ; t3.show() ; return 0 ; } Time::Time(int hour , int minute , int second){ this->hour = hour ; this->minute = minute ; this->second = second ; } Time Time::operator+(const Time &t) const { Time sum ; //使用默认构造函数 sum.second = second + t.second ; sum.minute = minute + t.minute + sum.second/60 ; sum.hour = hour + t.hour + sum.minute/60 ; sum.second %= 60 ; sum.minute %= 60 ; sum.hour %= 24 ; return sum ; } void Time::show()const { cout << "hour : " << hour << " minute : " << minute << " second : " << second << endl ; }

     Time t3 = t1 + t2 ;   使用重载+操作符  ,运算符右边的值是作为参数传递来的,  Time t3 = t1.operator+(t2) ;      这样使用也可以

    重载运算符不是一定是成员函数,也可以是非成员函数,但必须至少有一个操作数是用户定义的类型。如:

    #include<iostream>
    
    using namespace std ;
    class Time{ private : int hour , minute , second ; public : Time(int hour , int minute , int second) ; Time() {} //默认构造函数 Time operator+(const Time &t) const ; //友元函数 在函数中可以直接使用该类的私有成员 friend Time operator+(int h , const Time &t ) ; friend Time operator+(const Time &t , int h ) ; void show()const ; } ; int main(){ Time t1(3 , 20 , 30) ; Time t2(4 , 30 , 10) ; cout << "t1 : " ; t1.show() ; cout << "t2 : " ; t2.show() ; //重载操作符作为成员函数时,对象必须在操作符的左边 Time t3 = t1 + t2 ; cout << "t3 : " ; t3.show() ; //重载操作符作为非成员函数时,第一个参数在左边,第二个在右边 Time t4 = t1 + 5 ; cout << "t4 : " ; t4.show() ; Time t5 = 5 + t1 ; cout << "t5 : " ; t5.show() ; return 0 ; } Time::Time(int hour , int minute , int second){ this->hour = hour ; this->minute = minute ; this->second = second ; } Time Time::operator+(const Time &t) const { Time sum ; //使用默认构造函数 sum.second = second + t.second ; sum.minute = minute + t.minute + sum.second/60 ; sum.hour = hour + t.hour + sum.minute/60 ; sum.second %= 60 ; sum.minute %= 60 ; sum.hour %= 24 ; return sum ; } void Time::show()const { cout << "hour : " << hour << " minute : " << minute << " second : " << second << endl ; } //非成员函数 Time operator+(int h , const Time &t ) { Time sum ; sum.hour = (sum.hour + h)%24 ; return sum ; } Time operator+(const Time &t , int h ) { Time sum ; sum.hour = (sum.hour + h)%24 ; return sum ; }

    操作符重载的使用形式都同+操作符重载差不多,根据操作符的实际意义来判断返回值。

    友元:c++控制对类对象私有成员的访问,外界只能通过公有方法来访问,若外界也想使用类对象的私有成员,则我们可以将他们设置为类的友元,友元可以访问类对象的私有成员。

    友元有三种:

      友元函数:将函数设置为类的友元,则在函数中可以访问类的所有成员(包含私有成员)。

      友元类 :将类person设置为类Time的友元,则类person的成员函数可以访问类Time的所有成员(包含私有成员)。

      友元成员函数:将类person的成员函数setPerson()成员函数设置为类Time的友元,则在成员函数setPerson中可以访问类Time的所有成员(包含私有成员)。

    创建友元函数:将函数的声明放在类的声明中,前面加关键字friend,如:

    friend Time operator+(int h , const Time &t ) ;

    虽然,函数是在类声明中声明的,但它不是成员函数,虽然不是成员函数,但它与成员函数有相同的访问权限。

    编写函数定义时,它不是成员函数,不用在Time::限定符,另外,不用再定义总是用friend关键字。

    Time operator+(int h , const Time &t ) {
            Time sum ;
            sum.hour = (sum.hour +  h)%24 ;
            return sum ;
    }
    

     大部分重载运算符既可以用成员函数实现,也可以使用非成员函数实现,非成员函数应该是友元函数,否则不能访问类的私有数据,成员函数的第一个操作数是用this隐性传递的,非成员函数的所有操作数都是函数的参数,操作数的位置是根据参数的位置来定的。

    友元类:

    #include<iostream>
    using namespace std ;
    
    class Ta ;
    
    class Tc {
    public :
          /*class Ta在class Tc之前声明,可以使用Ta类名,不能使用类Ta的数据成员和成员函数,
          因为编译器不知道,如果该函数在这里实现就会出错,不知道ta.a
         */
    void changeA(Ta &ta) ;
    } ; class Ta { int a ; public : friend class Tb ; //友元类 在这里也声明了Tb,Ta知道了类名Tb friend void Tc::changeA(Ta &ta) ; //友元成员函数 因为Tc>声明在Ta之前,这里可以使用Tc::changeA(Ta &ta); 函数声明 Ta(int i) { a = i ; } int getA(){ return a ; } }; class Tb { public : void changeA(Ta &ta) { ta.a += 10 ; //可以访问Ta的私有成员 } } ; void Tc::changeA(Ta &ta) { //不能放在Tc类中实现,因为不能使用ta.a ta.a += 20 ; } int main(){ Ta ta(10) ; cout << "before : a : " << ta.getA() << endl ; Tb tb ; tb.changeA(ta) ; cout << "now : a : " << ta.getA() << endl ; return 0 ; }

      要先声明,才能够使用。因为Tc类中在Ta声明之前就使用了Ta类名,则我们应该使用class Ta声明Ta类名,因为Ta的成员还没有声明,所以在Tc类中不能使用Ta的数据成员ta.a,    这个我们应该好好理解下。

    类的自动转换和强制转换:

  • 相关阅读:
    CDN缓存
    nginx作用
    Linux下4个查找命令which、whereis、locate、find
    @ModelAttribute的用法,与@RequestBody的区别
    将kafka消息解析拷贝
    永久代溢出(java.lang.OutOfMemoryError: PermGen space )
    失败重试机制-递归应用1
    kafka-重复消费-2
    读写分离-延时问题-1
    UILabel处理html标签
  • 原文地址:https://www.cnblogs.com/taxuewuhen/p/3377006.html
Copyright © 2020-2023  润新知