美文网首页
运算符重载定义与友元函数

运算符重载定义与友元函数

作者: ag4kd | 来源:发表于2019-10-22 16:01 被阅读0次

    运算符重载定义

    returnType operator op(argument-list);
    

    这种方式成为成员重载运算符函数

    头文件

    //
    // Created by Biter on 2019/10/21.
    //
    
    #ifndef NDK_MYTIME_H
    #define NDK_MYTIME_H
    
    #include <iostream>
    
    using namespace std;
    
    class Time {
    private:
        int hours;
        int minutes;
    public:
        Time();
    
        Time(Time &time);
    
        Time(int h, int m = 0);
    
        void addMin(int m);
    
        void addHr(int h);
    
        Time sum(const Time &t) const;
    
        void show() const;
    
        void reset(int h = 0, int m = 0);
    
        Time operator +(const Time& time);//只看这个
        ~Time();
    
    };
    
    #endif //NDK_MYTIME_H
    

    实现文件

    //
    // Created by Biter on 2019/10/21.
    //
    #include "mytime.h"
    
    
    Time::Time() {
        hours = minutes = 0;
        std::cout << "默认构造函数" << std::endl;
    }
    
    Time::Time(Time &time) {
        hours = time.hours;
        minutes = time.minutes;
        std::cout << "拷贝构造函数" << std::endl;
    }
    
    Time::Time(int h, int m) {
        hours = h;
        minutes = m;
    
        std::cout << "双参构造函数" << std::endl;
    }
    
    Time::~Time() {
        std::cout << "析构函数" << std::endl;
    }
    
    void Time::addHr(int h) {
        hours += h;
    }
    
    void Time::addMin(int m) {
        minutes += m;
    }
    
    void Time::reset(int h, int m) {
        hours = h;
        minutes = m;
    }
    
    void Time::show() const {
        std::cout << "hours = " << hours << " ;minutes = " << minutes << std::endl;
    }
    
    Time Time::sum(const Time &t) const {
        Time time;
        std::cout << "局部函数对象的地址 = " << &time << std::endl;
        time.minutes = minutes + t.minutes;
        time.hours = hours + t.hours + time.minutes / 60;
        time.minutes %= 60;
        return time;
    }
    
    Time Time::operator+(const Time &time) {
        Time t;
    
        t.minutes = minutes + time.minutes;
        t.hours = hours + time.hours + t.minutes / 60;
        t.minutes %= 60;
        return t;
    }
    

    调用重载运算符

    //
    // Created by Biter on 2019/10/21.
    //
    
    #include "mytime.h"
    
    int main() {
        Time time;
        std::cout << "main 局部函数对象的地址 = " << &time << std::endl;
        time.reset(2, 90);
        Time time1;
        time1.reset(1, 10);
        time1 = time1 + time;
        time1.show();
        std::cout << "main 局部函数对象的地址 = " << &time1 << std::endl;
        return 0;
    }
    

    time1 = time1 + time;实则调用time1 = time1.operator+(time);

    注意,运算符op左侧是的对象是调用对象,右侧的对象是作为参数被传递的对象,即右侧为实参

    友元函数

    大多数运算符都可以通过成员或者非成员函数的方式来重载。

    从数学定义上来讲3.25 * timetime*3.25是等价的。后者可以通过重载乘法运算符来实现,前者则无法通过成员函数重载运算符的方式来实现,因为3.25不是类对象,不能调用成员函数。由此产生问题1:重载调用问题。

    非成员不是有对象调用的,它所使用的值都是显式的,比如

    Time t = 3.25 * time;
    

    该表达式与下面的调用匹配:

    Time t = operator*(3.25,time);
    

    该调用与下面的原型匹配:

    Time operator*(double m,const Time & t);
    

    对于非成员重载运算符来说,运算符表达式左边的操作数对应运算符函数的第一个参数,右边的操作数对应着第二个参数

    非成员函数解决了调用问题,但是这样存在一个新问题,它不能访问对下的私语属性,即产生问题2,访问问题

    然而,有一类特殊的函数可以访问类的私有属性,它们被称为友元函数

    创建友元函数

    前面讲述乘法操作符重过程中遇到的两个问题,一是操作符函数的调用问题,二是私有成员的访问问题,及其解决方案:友元函数

    第一步:声明友元函数。

    创建友元函数的第一步就是将其原型放在类的声明中,并在原型前面加上关键字friend

    friend Time operator*(double m,const & Time);
    
    • 这样声明的函数意味着:
    • 虽然函数实在类中声明的,但是他不是成员函数,因此不能使用成员重载的运算符来调用。
    • 虽然不是成员函数,但是有着与成员函数的相同的访问权限。

    第二步,定义友元函数

    因为不是成员函数,所以定义的时候不加类的作用域限定符,也就是函数定义前面不加Time::限定符,此外不要再定义中使用friend关键字:

    友元运算符重载函数

    上面提到过,对于非成员重载运算符来说,运算符表达式左边的操作数对应运算符函数的第一个参数,右边的操作数对应着第二个参数。这里只是深化以下这个应用。

    重载 <<

    Time trip;
    

    重载输出流操作符,使其可以输出一个对象

    cout<<trip;
    

    1、使用成员函数重载

    那么操作符左边的值必须是此类的对象,即

    trip<<cout;
    

    这种方式与以往的输出流用法有些不一致,显得编程不友好。

    2、使用友元函数重载操作符

    原型如下:

    void operator<<(ostream & os,const Time & time);
    

    实现如下:

    void operator<<(ostream & os,const Time & time){
        os<<t.hours<<" houes; "<<t.minutes<<" minutes";
    }
    

    调用

    cout<<trip;
    

    3、高级版本

    满足链式调用

    ostream & operator<<(ostream & os,const Time & time){
        os<<t.hours<<" houes; "<<t.minutes<<" minutes";
        return os;
    }
    

    成员还是友元

    成员函数重载运算符

    成员函数重载运算符,其参数比操作数少一个,因为其中一个被隐式地传递的调用对象。在原型中,做操作数被隐式地传递给函数,右操作数对应着参数对应。如:

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

    友元函数重载运算符

    友元函数重载运算符,其参数有操作数的木梳一样,两个操作数都作为参数传递。在原型中,左操作数对应第一个参数,右操作数对应第二个参数。如

    cout<<trip;
    
    ostream & operator<<(ostream & os,const Time & time){
        os<<t.hours<<" houes; "<<t.minutes<<" minutes";
        return os;
    }
    

    相关文章

      网友评论

          本文标题:运算符重载定义与友元函数

          本文链接:https://www.haomeiwen.com/subject/dzwqvctx.html