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

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

作者: 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;
}

相关文章

  • C++ 部分运算符重载

    可重载的运算符 不可重载的运算符和符号 重载运算符为类的成员函数 重载运算符为友元函数 重载赋值运算符 重载流插入...

  • 日记之旅第七天

    上午:重点讲解了函数重载,其中包括运算符重载,函数成员重载。运算符重载结合了昨天所讲的友元函数一起使用 下午:复习...

  • 第十一章 使用类(3)重载运算符

    (三)重载运算符: 1.作为友元非成员函数还是成员函数 两个操作数的运算符,如果运算符重载是成员函数版本,那么第...

  • 9.22总结

    一.知识点总结 1.运算符重载关键字operator 类型为重载运算符的返回类型 2.最常见的是友元函数与重载运算...

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

    运算符重载定义 这种方式成为成员重载运算符函数。 头文件 实现文件 调用重载运算符 time1 = time1 +...

  • 15.C++泛型

    模板函数 模板类 函数模板和友元函数 注意,只在重载左移右移运算符的时候使用友元函数,其他都不要用,友元函数容易导...

  • 11. 匿名对象、隐式构造、默认构造函数

    一.匿名对象 二.隐士构造函数 三. 四,友元函数 五.内部类 六.运算符重载

  • c++——函数符号重载2-15

    一般情况下,单目运算符最好重载为类的成员函数;双目运算符则最好重载为类的友元函数。以下一些双目运算符不能重载为类的...

  • C++运算符重载形式--成员函数or友元函数?

    1.C++操作符重载形式---成员函数or友元函数 1.对运算符重载,需要坚持四项基本原则:不可臆造运算符;运算符...

  • C++派生类的友元函数,派生类的析构函数

    一、赋值兼容 运算符重载函数需要访问父类的私有成员,运算符重载函数是父类的友元函数,子类继承了父类,子类也可以使用...

网友评论

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

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