精华内容
下载资源
问答
  • 用成员或友元函数重载运算符

    千次阅读 2020-06-14 17:33:25
    2.联系:不管是成员函数还是友元函数重载,运算符的: 使用方法相同。 传递参数的方式不同,实现代码不同,应用场合也不同 。 二. 用成员函数重载运算符 1.当一元运算符的操作数,或者二元运算符的左操作数是类的对象...

    一.运算符重载的两种形式

    运算符重载为类的成员函数或类的友元函数
    1.区别:
    成员函数具有this 指针,友元函数没有this指针
    2.联系:不管是成员函数还是友元函数重载,运算符的:
    使用方法相同。
    传递参数的方式不同,实现代码不同,应用场合也不同 。

    二. 用成员函数重载运算符

    1.当一元运算符的操作数,或者二元运算符的左操作数是类的对象时,定义重载算符函数为成员函数。
    在这里插入图片描述
    2. 二元运算符op
    如果要重载op 为类的成员函数,使之能够实现表达式oprd1 op oprd2,其中oprd1 为A 类对象,则op 应被重载为A 类的成员函数,形参类型应该是oprd2 所属的类型
    经重载后,表达式oprd1 op oprd2 相当于oprd1.operator op(oprd2)

    例 将“+”、“-”运算重载为复数类的成员函数

    #include<iostream>
    using namespace std;
    class Complex //复数类声明
    {
    public:
        Complex(double r=0.0,double i=0.0)
        {
            real=r;
            imag=i;
        }
        Complex operator + (Complex c2); //+重载为成员函数
        Complex operator - (Complex c2); //-重载为成员函数
        void display(); //输出复数
    private: //私有数据成员
        double real; //复数实部
        double imag; //复数虚部
    };
    Complex Complex::operator + (Complex c2) //重载函数实现
    {
        Complex c;
        c.real=real+c2.real;
        c.imag=imag+c2.imag;
        return Complex(c.real,c.imag);
    }
    Complex Complex::operator - (Complex c2) //重载函数实现
    {
        Complex c;
        c.real=real-c2.real;
        c.imag=imag-c2.imag;
        return Complex(c.real,c.imag);
    }
    void Complex::display()
    {
        cout<<"("<<real<<","<<imag<<")"<<endl;
    }
    int main() //主函数
    {
        Complex c1(5,4),c2(2,10),c3; //声明复数类的对象
        cout<<"c1=";
        c1.display();
        cout<<"c2=";
        c2.display();
        c3=c1-c2; //使用重载运算符完成复数减法
        cout<<"c3=c1-c2=";
        c3.display();
        c3=c1+c2; //使用重载运算符完成复数加法
        cout<<"c3=c1+c2=";
        c3.display();
    }
    
    

    3.前置运算符和后置运算符
    增1减1运算符是一元运算符。它们又有前置和后置两种。为了区分这两
    种运算,将后置运算视为二元运算符。表达式 obj++或obj–
    被看作为: obj++0或obj–0
    在这里插入图片描述

    若前置一元运算符重载为有返回值

    #include<iostream>
    using namespace std;
    class Clock //时钟类声明
    {
    public:
        Clock(int NewH=0, int NewM=0, int NewS=0)
        {
            Hour=NewH;
            Minute=NewM;
            Second=NewS;
        }
        void ShowTime()
        {
            cout<< Hour<<":"<<Minute<<":"<<Second<<endl;
        }
        Clock& operator ++(); //前置一元运算符重载
        Clock operator ++(int); //后置一元运算符重载
    private:
        int Hour,Minute,Second;
    };
    Clock& Clock::operator ++() //前置一元运算符重载函数有返回值
    {
        Second++;
        if(Second>=60)
        {
            Second=Second-60;
            Minute++;
            if(Minute>=60)
            {
                Minute=Minute-60;
                Hour++;
                Hour=Hour%24;
    
            }
        }
        return *this;
    }
    void main()
    {
        Clock myClock(23,59,59);
        cout<<"First time output:";
        myClock.ShowTime();
        cout<<"Show myClock++:";
        (myClock++).ShowTime();
        cout<<"Show ++myClock:";
        (++myClock).ShowTime();
    }
    
    
    

    当为后置时

    Clock Clock::operator ++(int)
    {
        Clock old=*this;
        Second++;
        if(Second>=60)
        {
            Second=Second-60;
            Minute++;
            {
                Minute=Minute-60;
                Hour++;
                Hour=Hour%24;
            }
        }
        return old;
    
    }
    

    若前置一元运算符重载为无返回值

    #include<iostream>
    using namespace std;
    class Clock //时钟类声明
    {
    public:
        Clock(int NewH=0, int NewM=0, int NewS=0)
        {
            Hour=NewH;
            Minute=NewM;
            Second=NewS;
        }
        void ShowTime()
        {
            cout<< Hour<<":"<<Minute<<":"<<Second<<endl;
        }
        void operator ++(); //前置一元运算符重载
        Clock operator ++(int); //后置一元运算符重载
    private:
        int Hour,Minute,Second;
    };
    void Clock::operator ++() //前置一元运算符重载函数无返回值
    {
        Second++;
        if(Second>=60)
        {
            Second=Second-60;
            Minute++;
            if(Minute>=60)
            {
                Minute=Minute-60;
                Hour++;
                Hour=Hour%24;
            }
        }
    }
    void main()
    {
        Clock myClock(23,59,59);
        cout<<"First time output:";
        myClock.ShowTime();
        cout<<"Show myClock++:";
        (myClock++).ShowTime();
        cout<<"Show ++myClock:";
    }
    
    

    若为后置时

    Clock Clock::operator ++(int)
    {
        Clock old=*this;
        Second++;
        if(Second>=60)
        {
            Second=Second-60;
            Minute++;
            if(Minute>=60)
    
            {
                Minute=Minute-60;
                Hour++;
                Hour=Hour%24;
            }
        }
        return old;
    
    }
    
    

    三.用友元函数重载运算符

    1.如果需要重载一个运算符,使之能够用于操作某类对象的私有成员,可以此将运算符重载为该类的友元函数。
    2.函数的形参代表依自左至右次序排列的各操作数。
    3.在第一个参数需要隐式转换的情形下,使用友元函数重载运算符是正确的选择
    4.友元函数没有this 指针,所需操作数都必须在参数表显式声明,很容易实现类型的隐式转换

    例 复数运算

    #include<iostream>
    using namespace std;
    class Complex
    {
    public:
        Complex( double r =0, double i =0 )
        {
            Real = r ;
            Imag = i ;
        }
        Complex(int a)
        {
            Real = a ;
            Imag = 0 ;
        }
        void print() const ;
        friend Complex operator+(const Complex &c1, const Complex &c2 ) ;
        friend Complex operator-(const Complex &c1, const Complex &c2 ) ;
        friend Complex operator- ( const Complex & c ) ;
    //前置一元运算符重载
    private:
        double Real, Imag ;
    };
    Complex operator + ( const Complex & c1, const Complex & c2 )
    {
        double r = c1.Real + c2.Real ;
        double i = c1.Imag+c2.Imag ;
        return Complex ( r, i ) ;
    }
    Complex operator - ( const Complex & c1, const Complex & c2 )
    {
        double r = c1.Real - c2.Real ;
        double i = c1.Imag - c2.Imag ;
        return Complex ( r, i ) ;
    }
    Complex operator- ( const Complex & c )
    {
        return Complex ( -c.Real, - c.Imag ) ;
    }
    void Complex :: print() const
    {
        cout << '(' << Real << " , " << Imag << ')' << endl ;
    }
    int main()
    {
        Complex c1( 2.5,3.7 ), c2( 4.2, 6.5 ) ;
        Complex c ;
        c.print() ;
        c = 25 + c2 ;
        c = c1 - c2 ;
        c.print() ;
        c = c2 + 25 ;
        c.print() ;
        c = - c1 ;
        c.print() ;
    
    }
    
    

    四.成员运算符函数与友元运算符函数的比较

    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 当 2 个对象相加时是没有顺序要求的,但要重载+让其与一个数字相加则有顺序要求,可以通过加一个友元函数使另一个顺序的输入合法。 class A{ …… A operator+(const A & obj); A operator+(const int b); ...

    当 2 个对象相加时是没有顺序要求的,但要重载 + 让其与一个数字相加则有顺序要求,可以通过加一个友元函数使另一个顺序的输入合法。

    class A
    {

    ……

                    A operator+(const A & obj);
                A operator+(const int b);
        friend A operator+(const int b, A obj);
                ……

    } ;

     

     

        A a1(1);
        A a2(2);
        A a3,a4;
        int m=1;
        a3=a1+a2;//可以交换顺序,相当月a3=a1.operator+(a2);
        a3.display();
        a4=a1+m;//因为加了个友元函数所以也可以交换顺序了。

     

    来自 <http://www.runoob.com/cplusplus/binary-operators-overloading.html>

     

     

     

    总结:

    C++允许对运算符进行重载,一般为operator op();当运算符函数为成员,则对象为第一操作数。

    当运算符函数为友元函数时,则第一个形参为第一操作数

    eg:

    如果运算符左侧的操作数属于C++标准类型(如int)或是一个其他类的对象,则运算符重载函数不能作为成员函数,只能作为非成员函数。如果函数需要访问类的私有成员,则必须声明为友元函数。

    <<运算符的重定义需要让ostream对象成为第一个操作数,因此<<运算符函数的重载必须定义为友元函数

     

     

     

    将双目运算符重载为友元函数时,在函数的形参表列中必须有两个参数,不能省略,形参的顺序任意,不要求第一个参数必须为类对象。但在使用运算符的表达式中,要求运算符左侧的操作数与函数第一个参数对应,运算符右侧的操作数与函数的第二个参数对应。如:

        c3=i+c2;  //正确,类型匹配

        c3=c2+i;  //错误,类型不匹配

     

    请注意,数学上的交换律在此不适用。如果希望适用交换律,则应再重载一次运算符“+”。如

        Complex operator+(Complex &c, int &i) //此时第一个参数为类对象

        {

            return Complex(i+c.real, c.imag);

        }

    这样,使用表达式i+c2和c2+i都合法,编译系统会根据表达式的形式选择调用与之匹配的运算符重载函数。可以将以上两个运算符重载函数都作为友元函数,也可以将一个运算符重载函数(运算符左侧为对象名的) 作为成员函数,另一个(运算符左侧不是对象名的)作为友元函数。但不可能将两个都作为成员函数,原因是显然的。

     

    来自 <http://c.biancheng.net/cpp/biancheng/view/217.html>

    展开全文
  • 用成员函数和友元函数重载运算符

    千次阅读 2019-05-20 10:25:04
    友元函数和成员函数选择 1.当无法修改左操作数的类时,使用...用友元函数重载<<、>>操作符 ostream& operator<<(ostream &out, Complex &c) istream& operator>>(istr...

    一元运算符

    首先明白什么是一元,二元和多元运算符,比如++a、b--属于一元运算符,因为参与运算的参数只有一个,以此类推二元运算符就是参与运算的参数有两个,比如a+b。

    一元运算符可以表示为:Object op\op Object

    重载为成员函数为:Object.operator op(),操作数有对象Object通过this指针隐含传递。

    重载为友元函数为:operator op(Object),操作数由参数表的参数Object提供。

    再开始分析自增,自减操作符时,我们要理解:

    前置自增、自减是参数先自增、自减运算完之后再使用(先运算,再使用)

    后置自增、自减是参数先使用再自增、自减(先使用,再运算)

    重载前置++和前置--操作符

    全局函数

    Complex &operator++(Complex &c)
    {
        c.m_a++;
        c.m_b++;
        return c;
    }
    
    int main()
    {
        Complex c(1, 2);
        ++c;
        c.PrintVal();
        system("pause");
        return 0;
    }

    成员函数

    class Complex 
    {
        Complex &operator--()
        {
            this->m_a--;
            this->m_b--;
            return *this;
        }
    };
    	
    int main()
    {
        Complex c(1, 2);
        --c;
        c.PrintVal();
        system("pause");
        return 0;
    }

    重载后置++和后置--操作符

    全局函数

    Complex operator++(Complex &c,int)
    {
        Complex temp = c;
        c.m_a++;
        c.m_b++;
        return temp;
    }
    
    int main()
    {
        Complex c(1, 2);
        c++;
        c.PrintVal();
        system("pause");
        return 0;
    }

    成员函数

    class Complex
    {
        Complex operator++(int)
        {
            Complex temp = *this;
            this->m_a++;
            this->m_b++;
            return temp;
        }
    };
    
    int main()
    {
        Complex c(1, 2);
        c++;
        c.PrintVal();
        system("pause");
        return 0;
    }

    对于下面参数中的int,是一个占位符,作用是与前置++,前置--相区别。编译器区分用的。

    Complex& operator++(Complex &c,int)
    Complex &operator++(int)

    运算符重载过程

    1、首先承认操作符重载是一个函数,定义函数名operator++

    2、分析函数参数,根据左右操作数的个数 operator++(Complex &c)

    3、分析函数返回值,函数返回值充当左值 需要返回一个引用

    友元函数和成员函数选择

    1.、当无法修改左操作数的类时,使用全局函数进行重载

    2、=、[]、()和->操作符只能通过成员函数进行重载

    3、类成员函数方法无法实现 << 操作符重载

    无法修改左操作数的类时,怎么理解?意思就是说我们无法修改ostream和istream类,只能通过全局函数进行重载,

    用友元函数重载<<、>>操作符

    • istream 和 ostream 是 C++ 的预定义流类
    • cin 是 istream 的对象,cout 是 ostream 的对象
    • 运算符 << 由ostream 重载为插入操作,用于输出基本类型数据
    • 运算符 >> 由 istream 重载为提取操作,用于输入基本类型数据
    • 用友员函数重载 << 和 >> ,输出和输入用户自定义的数据类型

    用友员函数重载 << 和 >> ,输出和输入用户自定义的数据类型

    friend ostream& operator<<(ostream &out, Complex &c)
    friend istream& operator>>(istream &in, Complex &c)

    注:函数返回值充当左值 需要返回一个引用

    友元函数重载操作符使用注意点

    1.友员函数重载运算符常用于运算符的左右操作数类型不同的情况

    2.在第一个参数需要隐式转换的情况下,使用友元函数重载

    3.友元函数没有this指针,所需操作数都必须在参数表中显示声明,很容易实现类型的隐式转换

    展开全文
  • C++用友元函数重载运算符

    千次阅读 2018-05-26 14:50:42
    声明方式:class Manage { friend ifstream &amp; operator&gt;&gt;(ifstream &amp; ReadFile, Manage &amp; user); }实现方式ifstream &amp; operator&...}调用方式ifst...

    声明方式:

    class Manage
    {
        friend ifstream & operator>>(ifstream & ReadFile, Manage & user);
    }

    实现方式

    ifstream & operator>>(ifstream & ReadFile, Manage & user)
    {
    }

    调用方式

    ifstream ReadFile;
    ReadFile >> user;

    我是在项目中遇到了很多问题之后分文件才这样实现的,若是在一个文件中实现方式应该更灵活。

    新手一枚,若有改进和错误请赐教。



    展开全文
  • } fenshu fenshu::operator+(fenshu& c2) //加法的重载 { int d3, num3, g; d3 = den * c2.den; num3 = num * c2.den + c2.num * den; g = gys(d3, num3); d3 = d3 / g; num3 = num3 / g; return fenshu(num3, d3);...
  • 现在先说说赋值运算符“=”的重载C++规定赋值运算符“=”只能重载为类的非静态成员函数,而不可以重载为类的友元函数。不能重载为类的静态成员应该比较容易理解,因为静态成员函数是属于整个类的,不是属于某个对象...
  • 使用友元函数重载运算符

    千次阅读 2018-10-05 21:41:01
    2. 为什么要用友元函数重载运算符?  首先如果是在类内重载的运算符函数,都默认有一个 *this 指针,所以此时对二元运算符重载的话只能放一个形参。  比如:  int A =0;  A = B * 5; // B是一个自定义...
  • #include &lt;iostream&gt;using namespace std; class Complex  {private: double real; double imag;public:  Complex(double r=0.0,double i=0.0); void print();Complex operator+(Complex a);...
  • c++知识点----友元函数重载运算符

    千次阅读 2017-09-29 21:09:45
    友元函数重载运算符“+”,使两个对象real相加,imag相加。输出相加后的对象的值加以验证 使用到的文件 main.cpp #include using namespace std; #include "class.h" int main() { complex
  • 1.对双目运算符而言,成员函数重载运算符的函数参数表中只有一个参数,而用友元函数重载运算符函数参数表中含有两个参数。  对单木运算符来说,成员函数重载运算符的函数参数表中没有参数,而用友元函数重载运算符...
  • 友元函数 什么是友元函数 私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口(成员函数)间接地进行。这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序...
  • 如何重载运算符(以 + 为例); 运算符重载与友元函数; ( << )运算符的重载; 类的友元函数 通常来说,外部实现对类私有成员的访问,只能通过类的公有方法,然而友元提供了另一用方法。 友元函数 友元类...
  • 以下是对C++运算符重载 成员函数与友元函数进行了介绍,需要的朋友可以过来参考下
  • 一个实例,实现运算符重载(成员函数和非成员函数两种方式),友元函数的使用,注意事项等,自己学习时编写的,
  • 友元函数作为重载运算符的方式重载运算符+ 下面的例子来自于课本 #include using namespace std; class Complex { public: Complex() { real = 0; imag = 0; } Complex(double
  • c++ 类的使用 友元函数 重载运算符

    千次阅读 2016-03-25 15:53:30
    #ifndef S_H_ #define S_H_ #include "iostream" ... //不给任何参数的默认构造函数 如果写了 给参的构造函数且不写这个无参的构造函数的话 那么错误 这个构造函数不存在 s(int h, int m); void show(voi
  • 输出流函数重载为成员方法以及全局函数 ①以下输出流重载为成员方法虽然解决了this指针抢占第一个参数的问题,但方法的调用必须用对象去驱动如下: t1 << cout ; 或 t1 << cout << endl; 这种...
  • 友元函数重载+运算符

    千次阅读 2018-12-20 23:47:20
    #include&lt;iostream&gt; //#include&lt;vector&gt; using namespace std;... Vector(){}//定义无参构造函数并赋初值为0;... Vector(int i,int j)//重载构造函数; { a=i; ...
  • c++友元函数运算符重载

    千次阅读 2019-03-13 15:10:10
     c++的类和java的类机制着实不大一样,不仅仅是语法,还包括一些特殊的东西,如c++用友元函数来破坏类的封装性,使得外界(友元函数体)可以访问类的私有属性,而java呢,java则可以通过反射机制类在类的外部访问类...
  • 模板类友元函数运算符重载

    千次阅读 2017-07-20 22:38:45
    模板类友元函数运算符重载类模板可以定义友元函数以及进行运算符重载,下面给出友元函数实现以及操作符重载#include<iostream>using namespace std;template class myclass { T x; T y; public: myclass(T t1=...
  • 但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高了程序的运行...
  • 先上题:下列运算符都可以被友元函数重载的是: A)=,+,-,\ B)[],+,(),new C)->,+,*,>> D)<<,>>,+,* 正确答案为D 我们知道,在运算符重载,友元函数运算符重载函数与成员运算符重载函数的...
  • /*  ... *All rights reserved.... *文件名称:test.cpp  *作 者:陈传祯  ...*问题描述:简单的运算符重载  *输入描述: 两个复数,  *程序输出: 两个复数相加减的结果  */  #include 
  • C++ 友元函数实现运算符重载

    千次阅读 2019-01-05 22:18:24
    C++:友元函数实现流运算符重载 友元函数实现 除一般符号外,还可以重载的特殊符号有: &gt;&gt;(流提取运算符)返回类型必须是istream&amp; operator&gt;&gt;(istream&amp;in,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,665
精华内容 7,466
关键字:

友元函数的重载运算符