第九天2017/04/18(1、友元函数、运算符重载)

来源:互联网 发布:sam软件csp 编辑:程序博客网 时间:2024/05/17 15:06

1、成员函数和全局函数(友元函数)转换的技巧

从类的成员函数转换为全局函数,只需要加一个this指针;从全局函数转换为类的成员函数,需要减去一个左操作数参数。【友元函数、成员函数】唯一的区别:    友元函数中没有this指针,而成员函数中有this————>因此友元函数的参数要比成员函数的参数多一个。【技巧】    友元函数的多出来的参数相当于成员函数中隐藏的this指针指向的对象*this,例如:        friend String operator+(const String& s1,const String& s2); //s1的作用        String operator+(const String& s);   //相当于成员函数中的*this        friend String operator+(const String& s,const char* str);//s的作用        String operator+(const char* str);  //相当于成员函数中的*this        friend String operator+=(String& s1, const String& s2); //s1的作用         String operator+=(const String& s);//相当于成员函数中的*this        friend String operator+=(String& s,const char* str);//s的作用        String operator+=(const char* str);//相当于成员函数中的*this

2、友元函数

//详细讲解:operator+函数的返回值是对象?还是对象的引用?以及各自对应的正确写法!#include <iostream>using namespace std;class Complex{public:    Complex(double r=0,double i=0) {real=r;imag=i;}//重载函数作为友元函数//形式1:错误    friend Complex& operator+(Complex &c1,Complex &c2)  //【此处代码是错误的】返回的是引用Complex&     {        Complex tmp;        tmp.real = c1.real+c2.real;        tmp.real = c1.imag+c2.imag;        return tmp;        //返回一个临时对象的简写:return Complex(c1.real+c2.real, c1.imag+c2.imag);    ////可以修改成:在被调函数中动态给对象分配空间,这样可以把结果甩出去    //  Complex *tmp = new Complex;    //  tmp->real = c1.real+c2.real;    //  tmp->real = c1.imag+c2.imag;    //  return *tmp;    }    //分析形式1为什么错误?  答:因为返回值为对象的引用时,返回的内容如果是临时对象,在函数            //执行结束后,临时对象被析构,因此返回一个无效的值。//形式2:正确    friend Complex  operator+(Complex &c1,Complex &c2) //【此处代码是正确的】返回的是对象Complex    {        Complex tmp;        tmp.real = c1.real+c2.real;        tmp.real = c1.imag+c2.imag;        return tmp;        //返回一个临时对象的简写:return Complex(c1.real+c2.real, c1.imag+c2.imag);    }    //分析形式2为什么正确?  答:因为返回值为对象时,“调用时operator+(c1,c2);返回的    //内容也是临时对象”,但是返回时会调用拷贝构造函数另外创建一个对象来保存临时对象tmp的    //值,因此尽管在函数执行结束后,临时对象被析构,但是拷贝构造出来的对象可以返回给主函    //数,被主函数中的对象接受。    void display()    {        cout<<"real="<<real<<","<<"imag="<<imag<<endl;    }private:    double real;    double imag;};int main( ){    Complex c1(3,4),c2(5,1),c3;    c3=c1+c2;    c1.display();    c2.display();    c3.display();}

3、运算符重载
注:
不能重载的运算符有 . .* sizeof :: ?:
常用的重载运算符有 [] = ++ – == !=
C++中不能用友元函数重载的运算符有: = ( ) [ ] ->

#include <iostream>using namespace std;class Complex{public://构造函数:写成下面三个,看起来啰嗦,其实是为了防止调用时发生二义性    Complex(){real=0; imag=0;}      Complex(double r,double i) {real=r;imag=i;}    Complex(double r){real=r;imag=0;} //转换构造函数/*-------------------------------------------------------------------*///重载 +//case1:重载运算符函数为成员函数(左操作数由this指针传递,右操作数由参数传递)    Complex operator-(Complex & obj) //返回类型Complex       {        Complex tmp;        tmp.real = real+obj.real;        tmp.imag = imag+obj.imag;        return tmp;    }//case2:重载运算符函数为友元函数(左、右操作数由参数传递)    friend Complex operator+(const Complex& c1,const Complex& c2)  //返回类型Complex    {        return Complex(c1.real+c2.real, c1.imag+c2.imag);      }/*-------------------------------------------------------------------*///重载前置++、--    Complex& operator--()  //成员函数    {        return Complex(--real,--imag);  // 返回类型都是引用Complex&    }    friend Complex& operator++(Complex& obj)  //友元函数    {        return Complex(++obj.real,++obj.imag); //形参和返回类型都是引用Complex&    }//重载后置++、--    Complex operator++(int)  //成员函数    {        Complex tmp = *this;        this->real++;        this->imag++;        return tmp;    }    friend Complex operator--(Complex& obj,int)  //友元函数    {        Complex tmp = obj;        obj.real--;        obj.imag--;        return tmp;    }/*-------------------------------------------------------------------*///重载 <<    friend ostream& operator<<(ostream& out,Complex& obj)      {        out<<"real="<<obj.real<<","<<"imag="<<obj.imag;        return out;    }    //friend void operator<<(ostream& out,Complex& obj)  //这样不能连续输出    //{    //  out<<"real="<<obj.real<<","<<"imag="<<obj.imag;    //}//【疑问】为什么返回值是ostream& ,而不是void?    //【答】为了能够连续的输出;  ||    注:函数返回值当作左值,则必须返回一个引用!/*-------------------------------------------------------------------*/private:    double real;    double imag;};int main(){    Complex c1(3,4),c2(5),c3;    c3 = c1 + c2;    //cout<<c1;//等价于operator<<(cout,c1);,调用完成后,返回值为cout,可以作为左值继续输出!    cout<<c1<<endl; //等价于operator<<(operator<<(cout,c1),c1);    cout<<c2<<endl;    cout<<c3<<endl;    c3 = 20 + c3;  //这种情况必须用友元函数    cout<<c3<<endl;    c3--;    cout<<c3<<endl;}
【总结规律】//【返回类型:对象Complex、String】①  +  -  *  /  %  +=  -=  *=  /=  %=  基本的四则运算    friend String operator+(const String& s1,const String& s2);    String operator+(const String& s);      friend String operator+(const String& s,const char* str);    String operator+(const char* s);      friend String operator+=(String& s1, const String& s2);      String operator+=(const String& s);    friend String operator+=(String& s,const char* str);    String operator+=(const char* str);②单目运算符:后置++、后置--    Complex operator++(int);     friend Complex operator--(Complex& obj,int);------------------------------------------------------------------------//【返回类型:对象的引用Complex&、String&】Complex& operator--();//前置++、前置--①连续操作:>> 、 << 、 赋值=    friend ostream& operator<<(ostream& out,Complex& obj);    Complex& operator=(const Complex& obj);②返回值作为“左值”    char& operator[](int i); // []操作符========================================================================================【综合示例】//String类//-------------------------------------------------------------------//重载 =  :返回的是String&,“连等a=b=c”    String& operator=(char *s);    String& operator=(const String& s);//-------------------------------------------------------------------//重载 +  :返回的是String (s=s1+s2;因为如果用String&,会使在执行完+后,s1的值也发生变化)    //friend String operator+(const String& s1,const String& s2);    String operator+(const String& s);      //friend String operator+(const String& s,const char* str);    String operator+(const char* s);  //重载 += :返回的是String    //friend String operator+=(String& s1, const String& s2);      String operator+=(const String& s);    //friend String operator+=(String& s,const char* str);    String operator+=(const char* str);//-------------------------------------------------------------------//重载 [] :返回的是char&    char& operator[](int i);    const char& operator[](int i) const;//重载 <<  >> :返回的是ostream&    friend ostream& operator<<(ostream &out,String &s);    friend istream& operator>>(istream &in ,String &s);//-------------------------------------------------------------------//friend函数:重载> < == !=     friend bool operator<(const String& s1,const String& s2);    friend bool operator>(const String& s1,const String& s2);    friend bool operator==(const String& s1,const String& s2);    friend bool operator!=(const String& s1,const String& s2);
1 0
原创粉丝点击