14运算符重载

C++的所有运算符都可以被重载吗?

 .   .*   ::   ?:   sizeof 不能被重载

 

什么情况下需要考虑运算符重载?

当要把自定义类的对象用作运算符的操作数时,可以被重载的运算符中只有赋值运算符 = 和地址运算符 & 可直接用于对象的操作

 

运算符重载函数如何定义?

保持运算符的原有属性,作为类的成员函数或友元函数、作为一般函数

特例:( ) [ ] ->  = 及类型转换运算符的重载

 

运算符的重载函数定义为类的成员函数

1.当该成员函数不带参数时,支持以该类对象为唯一操作数的运算

2.当该成员函数带一个参数时,支持以该类对象为左操作数、以所带参数类型的数据为右操作数的运算

 

运算符的重载函数定义为类的友元函数

1.当该函数带一个参数时,支持以该参数类型的对象为唯一操作数的运算

2.当该函数带两个参数时,支持以第一个参数类型的数据为左操作数、以第二个参数类型的数据为右操作数的运算

 

在包含对象的双目运算中,当双目运算符的左操作数不是某类的对象时,重载函数不能定义为该类的成员函数

流插入运算符<<的重载,运算符可交换性的实现(两个不同类型的操作数)

运算符重载函数的定义要保证运算无二义性

 

注意:

操作数是自定义类的对象或对象的引用

作为成员函数重载,没有参数

作为友元函数重载,参数为自定义类的对象或对象的引用

 

单目运算符重载

特殊的单目运算符++、--

  以++ 为例( -- 同理) ,设b为类C的对象。。。。

前自增,如:++b

重载函数可为C的成员函数,原型为

     返回值类型  operator++();

重载函数也可为C的友元函数,原型为

     返回值类型  operator++(C &);

 

后自增,如:b++ 

重载函数可为C的成员函数,原型为

   返回值类型  operator++(int);

 b++转换为函数调用b.operator++(0)

重载函数也可为C的友元函数,原型为

   返回值类型  operator++(C &, int);

 b++转换为函数调用operator++(b,0)

 

 

双目运算符重载

一般双目运算符的重载要考虑两个因素:

1.被重载运算符的左操作数是什么数据类型

2.是否要保留运算符的可交换性(只针对具有可交换性的运算符而言)

双目运算符的重载可实现为

  1. 带有一个参数的(非静态)成员函数(左操作数必须为该类的对象或对象的引用)
  2. 带有两个参数的非成员函数(其参数之一必须是类的对象或对象的引用)

 

赋值运算符重载

赋值运算符可直接用在自定义类的对象赋值,其默认操作是逐个拷贝对象的所有数据成员

如果对象中包含动态分配的空间时,这种赋值方式就有可能出错,如

    String s1("abc"),s2("def"),&s3=s1;

    s1 = s2;

  对象s1和s2中都只有一个数据成员str,在赋值操作后,对象s1和s2的指针str都指向了同一块数据空间(即存放了"def"的存储空间)

 

 

例子 一:复数的+、-、=运算

// 文件1:complex1.h--复数类的定义

  #ifndef  _COMPLEX1_H

  #define  _COMPLEX1_H

  class Complex

 {public:

  Complex(double = 0.0, double = 0.0);    

  Complex operator+(const Complex&) const;    

  Complex operator-(const Complex&) const;

  Complex& operator=(const Complex&);     

  void print() const;                     

  private:

  double real;       // real part

  double imaginary;  // imaginary part

 };

  #endif

//文件2:complex1.cpp--复数类的成员函数定义

  #include <iostream.h>

  #include "complex1.h"

  Complex::Complex(double r, double i)

  {  real = r;

     imaginary = i;

  }

  Complex Complex::operator+(const Complex

                        & operand2) const

  {Complex sum;

   sum.real = real + operand2.real;

   sum.imaginary = imaginary +

                   operand2.imaginary;

   return sum;

  }

Complex Complex::operator-(const Complex

                       & operand2) const

  {Complex diff;

   diff.real = real - operand2.real;

   diff.imaginary = imaginary –

                    operand2.imaginary;

   return diff; }

  Complex& Complex::operator=(const

                 Complex & right)

  {real = right.real;

   imaginary = right.imaginary;

   return *this; }

  void Complex::print( ) const

  {cout<<'('<<real<< ", " << imaginary

       << ')'; }

//文件3: FIG13_1.cpp--主函数定义

  #include <iostream.h>

  #include "complex1.h"

  main()

  {Complex x, y(4.3, 8.2), z(3.3, 1.1);

   cout << "x: ";

   x.print();

   cout << "\ny: ";

   y.print();

   cout << "\nz: ";

   z.print();

   x = y + z;

   cout << "\n\nx = y + z:\n";

   x.print();

   cout << " = ";

   y.print();

   cout << " + ";

   z.print();

   x = y - z;

   cout << "\n\nx = y - z:\n";

   x.print();

   cout << " = ";

   y.print();

   cout << " - ";

   z.print();

   cout << '\n';

   return 0;}

例子二:重载运算符 ! ,以判断对象中的字符串是否为空串

//文件string.h

  #if !defined  __STRING__H__

  #define  __STRING__H__

  #include <stdlib.h> 

  class String

  {public:

       String(char *m="");

        ~String();

        //定义运算符重载成员函数原型

        bool operator !( );

   private:

        char *str;

  }; 

  #endif

//文件String.cpp

  #include <string.h>

  #include "string.h" 

  String::String(char *m)

  {str = new char[strlen(m)+1];

   strcpy(str,m);

  } 

  String::~String()

  {delete [] str;}

  bool String::operator !() //实现运算符重载

  {if (strlen(str) == 0)

           return true;

   return false;

  }

  #include <iostream.h>

  #include "String.h" 

  main( )

  {String s1, s2("some string");

   if (!s1) //括号中等价于s1.operator!()

           cout<<"s1 is NULL!"<<endl;

   else

           cout<<"s1 is not NULL!"<<endl;

   if (!s2)

           cout<<"s2 is NULL!"<<endl;

   else

           cout<<"s2 is not NULL!"<<endl;

   return 0;

  }

 

例子三:重载流插入运算符<<和流提取运算符>>

//文件string.h

 #if !defined __STRING__H__

 #define __STRING__H__

 #include <iostream.h> 

 class String

 {friend ostream & operator<<(ostream

                   &output, String &s);

      friend istream & operator>>(istream

                   &input, String &s);

  public:

       String(char *m=" ");

       ~String();

  private:

       char *str;

 }; #endif

//文件string.cpp

 #include <string.h>

 #include "string.h" 

 String::String(char *m)

 {str = new char[strlen(m)+1];

  strcpy(str,m);

 }

 

 String::~String()

 {

      delete [] str;

 }

//定义运算符<<和>>的重载函数

 ostream & operator<<(ostream &output,

                      String &s)

 {output << s.str;

     return output;

 } 

 istream & operator>>(istream &input,

                      String &s)

 {char temp[1000];

  cin >> temp;

  delete [] s.str;

  s.str = new char[strlen(temp)+1];

  strcpy(s.str,temp);

  return input;

 }

#include "string.h" 

 main()

 {String s1,s2;

  cout << "Please input two strings: "

       << endl;

  cin >> s1 >> s2;

  cout << "Output is: " << endl;

  cout << "s1 -- " << s1

       << endl << "s2 -- " <<s2 << endl;

  return 0;

 }

 

例子四:重载运算符+=使x+=y实现将对象y中的字符串连接到对象x的字符串后面

//文件string.h,定义类String

 #if !defined  __STRING__H__

 #define __STRING__H__

 #include <iostream.h> 

 class String

 {friend ostream & operator<<(ostream

                   &output, String &s);

  friend istream & operator>>(istream

                   &input, String &s);

  public:

   String(char *m="");

   ~String();

   String & operator+=(String &s);

  private:

   char *str;};

#endif

//文件string.cpp,类String的实现

 #include <string.h>

 #include "string.h" 

 String::String(char *m)

 {str = new char[strlen(m)+1];

  strcpy(str,m);

 } 

 String::~String()

 {delete [] str;}

 //定义运算符<<的重载函数

 ostream & operator<<(ostream &output,

                      String &s)

 {output<<s.str;

  return output;

 }

//定义运算符>>的重载函数

 istream & operator>>(istream &input,

                       String &s)

 {char temp[1000];

  cin>>temp;

     delete [] s.str;

     s.str = new char[strlen(temp)+1];

  strcpy(s.str,temp);

  return input;

 }

//定义运算符+=的重载函数 

 String &String::operator+=(String &s)

 {char temp[4096]; //不是最好的实现

  strcpy(temp,str);

  strcat(temp,s.str);

  delete []str;

  str = new char[strlen(temp)+1];

  strcpy(str,temp);

  return *this;

 }

#include "string.h"  

 main()

 {String s1,s2;

  cin>>s1>>s2; //输入字符串Wuhan和Changsha

  cout<<"s1 -- "<<s1<<endl;

  s1+=s2;

  cout<<"s1 after s1+=s2 -- "<<s1<<endl;

  return 0;

 }

 

例子五:重载运算符+和=,使得类String的对象x、y、z可以执行表达式 x = y + z 

//文件string.h,定义类String

 #if !defined __STRING__H__

 #define __STRING__H__

 #include <iostream.h> 

 class String

  {friend ostream & operator<<(

              ostream &output, String &s);

   friend istream & operator>>(

              istream &input, String &s);

   public:

        String(char *m="");

        ~String();

        String & operator=(String &s);

        String & operator+(String &s);

   private:  char *str; };

 #endif

//文件string.cpp,类String的实现

 #include <string.h>

 #include "string.h" 

 String::String(char *m)

 {str = new char[strlen(m)+1];

  strcpy(str,m);

 } 

 String::~String()

 {delete [] str; }

 ostream & operator<<(

              ostream &output, String &s)

 {output<<s.str;

  return output;

 }

//定义运算符>>重载函数

 istream & operator>>(

                istream &input, String &s)

 {

      char temp[1000];

      cin>>temp;

      delete [] s.str;

      s.str = new char[strlen(temp)+1];

      strcpy(s.str,temp);

      return input;

 }

String &String::operator=(String &s)

 {

      if (&s == this)   //检查是否自我赋值,非常重要

           return *this;

      delete []str; //释放当前对象的数据空间

      str = new char[strlen(s.str)+1];

                 //重新分配适当大小的空间

      strcpy(str, s.str);

      return *this;

 }

String &String::operator+(String &s)

 {

      static String res;

            //为什么要声明res为静态对象?

      char temp[4096];

      strcpy(temp,str);

      strcat(temp,s.str);

      delete [] res.str;

      res.str = new char[strlen(temp)+1];

      strcpy(res.str,temp);

      return res;

 }

 

#include "String.h" 

 main()

 {String s1,s2;

  cout << "Please input two strings: "

       << endl;

  cin >> s1 >> s2;

  cout << "Output is: " << endl;

  cout << "s1 -- " << s1 << endl;

  cout << "s2 -- " <<s 2 << endl;

  s1 = s1 + s2;

  cout << "after s1 = s1 + s2;" << endl;

  cout << "s1 -- " << s1 << endl;

  return 0;

 }

 

posted @ 2018-01-09 16:51  gd_沐辰  阅读(190)  评论(0编辑  收藏  举报