zoukankan      html  css  js  c++  java
  • 运算符重载和友元函数

    1. 运算符重载

    c++允许将运算符重载扩展到用户定义的类型,例如:允许使用+将两个对象相加,编译器将根据操作数的数目和类型决定使用哪种加法定义,重载运算符可以使代码看起来更加自然。

    例:计算时间,一个运算符重载的实例:

    class Time {
    private:
        int hours;
        int minutes;
    public:
        Time() {}
        Time(int hours, int minutes) {
            this->hours = hours;
            this->minutes = minutes;
        }
    
        void setHours(int hours) {
            this->hours = hours;
        }
    
        int getHours() {
            return this->hours;
        }
    
        void setMinutes(int minutes) {
            this->minutes = minutes;
        }
    
        int getMinutes() {
            return this->minutes;
        }
    
        Time operator+(const Time& t) const {
            Time sum;
            sum.minutes = t.minutes + this->minutes;
            sum.hours = t.hours + this->hours + sum.minutes / 60;
            sum.minutes = sum.minutes % 60;
            return sum;
        }
    
        Time operator*(double mult) const {
            Time result;
            long totalMinutes = hours * mult * 60 + minutes * mult;
            result.hours = totalMinutes / 60;
            result.minutes = totalMinutes % 60;
            return result;
        }
    };

    测试:

    2. 友元函数

     运算符重载中,下面的语句

    A = B * 3.5

    将被转成下面的成员函数调用

    A = B.operator*(3.5)

    但是下面的语句又会如何呢

    A = 3.5 * B;  // cannot correspond to a member function

    解决这个问题的一种方式是,告诉每个人,只能按照B * 3.5这种格式编写,这是一种对服务器友好-客户警惕的解决方案,与OOP无关

    还有一种方式:非成员函数,非成员函数不是由对象调用的,它使用的所有值都是显式参数,这样编译器能够将下面的表达式

    A = 3.5 * B

    与非成员函数匹配

    A = operator*(3.5, B);

    该函数的原型如下:

    Time operator*(double m, const Time& t);对于非成员重载运算符函数而言,运算符左边的操作数等于操作符函数的第一个参数,运算符表达式右边的操作数对应于运算符函数的第二个参数。

    使用非成员函数可以按照所需的顺序获得操作数,但是引发了一个新的问题,非成员函数不能直接访问类的私有数据,至少常规非成员函数不能访问,然而有一类特殊的非成员函数可以访问类的私有成员,被称为友元函数

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

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

    该原型意味着两点:

    1. 虽然operator*()函数都是在类声明中声明的,但是不是成员函数,因此不能使用成员运算符来调用;

    2. 虽然operator*()函数不是成员函数,但是它与成员函数的访问权限相同

    第二步是编写函数的定义,因为它不是成员函数,所以不需要使用Time::限定符

    常见的友元:重载<<运算符

  • 相关阅读:
    win10 ObservableCollection 排序自动收缩问题
    在C#中GUID生成的四种格式
    MultiBinding的StringFormat参数问题
    asp.net mvc cookie超时返回登录页面问题
    string.Format的困惑
    c# web应用调试开启外部访问
    主码索引、聚集索引、非主码索引(辅助索引)、唯一索引、外键索引、复合索引、非主码索引、聚集主码(聚集索引)、单列索引、多列索引、普通索引等
    优化MD5和IP在(MySQL)数据库中的存储
    《Effective MySQL之SQL语句最优化》读书笔记——乱七八糟系列(给自己看)
    布隆过滤器(Bloom Filter)文章收集
  • 原文地址:https://www.cnblogs.com/feng-ying/p/10532968.html
Copyright © 2011-2022 走看看