zoukankan      html  css  js  c++  java
  • C++重载运算符

    1.运算符重载的本质就是类对象调用一个运算符重载函数。比如说重载“+”运算符,其实是在调用operator+()这个函数。为支持多种运算,一个运算符可能有好几个同名的运算符重载函数,此时C++编译器会根据调用对象的类型决定调用哪个重载函数。例如在实现加法运算(+)时,C++编译器会根据+号左右两侧的元素类型,决定调用哪个重载函数。

    例如:

     1 //.h文件
     2 #pragma once
     3 class Complex
     4 {
     5 public:
     6     Complex(int A=0,int B=0);
     7     ~Complex(void);
     8     Complex operator+(Complex&);
     9     Complex operator+(int&);
    10     void printC(void);
    11 
    12 private:
    13     int a;
    14     int b;
    15 };
    16 
    17 
    18 //.cpp文件
    19 #include "Complex.h"
    20 #include<iostream>
    21 
    22 
    23 Complex::Complex(int A,int B)
    24 {
    25     a=A;
    26     b=B;
    27 }
    28 
    29 
    30 Complex::~Complex(void)
    31 {
    32 }
    33 
    34 Complex Complex::operator+(Complex& temp)
    35 {
    36     Complex c(this->a+temp.a,this->b+temp.b);
    37     return c;
    38 }
    39 
    40 Complex Complex::operator+(int& temp)
    41 {
    42     Complex c(this->a+temp,this->b);
    43     return c;
    44 }
    45 
    46 void Complex::printC(void)
    47 {
    48     std::cout<<a<<"+"<<b<<"i"<<std::endl;
    49 }
    50 
    51 
    52 //main函数
    53 #include<iostream>
    54 #include "Complex.h"
    55 
    56 using namespace std;
    57 
    58 
    59 
    60 int main()
    61 {
    62     int i=5;
    63     Complex c1(1,2),c2(3,4);
    64 
    65     Complex c3=c1+c2;
    66     c3.printC();
    67 
    68     Complex c4=c1+i;
    69     c4.printC();
    70     
    71 
    72     system("pause");
    73     return 0;
    74 }

    2.C++中的重载运算符如果访问的是类的私有属性,除了把重载运算符函数写在类的里面作为成员函数,还可以将重载运算符函数写在类的外面,但此时重载运算符函数要被声明为友元函数,否则将无法访问类的私有属性。例如对上面的重载"+"运算符,如果将重载运算符函数写在类体的外面,可以写成:

    friend Complex operator+(Complex& c1,Complex& c2);//在类体里面声明重载运算符函数为由原函数

    //重载运算符函数在类体外的实现

    Complex operator+(Complex& c1,Complex& c2)

    {

        Complex c(c1.a+c2.a , c1.b+c2.b);

        return c;

     3.C++重载单目运算符,如"--"运算符时,由于"--"运算符有两种用法:--a(前置)  和  a++(后置)    所以重载"--"运算符时,写重载函数的时候就需要注意了,必须使重载函数的函数输入参数有所区别。可是"--"运算符写在类里面时,无须输入函数参数,为了区别前置"--"和后置"--"的重载函数,这时候我们就需要使用占位符了。

    例如:

      1 //.h文件
      2 #pragma once
      3 class Complex
      4 {
      5 public:
      6     Complex(int A=0,int B=0);
      7     ~Complex(void);
      8     Complex operator+(Complex&);
      9     Complex operator+(int&);
     10     //friend Complex operator+(Complex& c1,Complex& c2);
     11 
     12     Complex& operator--(void);//前置--
     13     Complex operator--(int);//后置-- ,int是占位符
     14     void printC(void);
     15 
     16 private:
     17     int a;
     18     int b;
     19 };
     20 
     21 
     22 //.cpp文件
     23 #include "Complex.h"
     24 #include<iostream>
     25 
     26 
     27 Complex::Complex(int A,int B)
     28 {
     29     a=A;
     30     b=B;
     31 }
     32 
     33 
     34 Complex::~Complex(void)
     35 {
     36 }
     37 
     38 //********************************************重载"+"运算符****************************************
     39 Complex Complex::operator+(Complex& temp)
     40 {
     41     Complex c(this->a+temp.a,this->b+temp.b);
     42     return c;
     43 }
     44 
     45 Complex Complex::operator+(int& temp)
     46 {
     47     Complex c(this->a+temp,this->b);
     48     return c;
     49 }
     50 
     51 
     52 /*
     53 Complex operator+(Complex& c1,Complex& c2)
     54 {
     55     Complex c(c1.a+c2.a,c1.b+c2.b);
     56     return c;
     57 }
     58 */
     59 
     60 
     61 
     62 //********************************************重载"--"运算符****************************************
     63 //前置--
     64 Complex& Complex::operator--()
     65 {
     66     this->a--;
     67     this->b--;
     68 
     69     return *this;//返回的是一个引用,即this指针指向的对象本身
     70 }
     71 
     72 
     73 //后置--
     74 Complex Complex::operator--(int)
     75 {
     76     Complex temp=*this;
     77 
     78     this->a--;
     79     this->b--;
     80 
     81     return temp;
     82 }
     83 
     84 
     85 void Complex::printC(void)
     86 {
     87     std::cout<<a<<"+"<<b<<"i"<<std::endl;
     88 }
     89 
     90 
     91 //main函数
     92 #include<iostream>
     93 #include "Complex.h"
     94 
     95 using namespace std;
     96 
     97 
     98 
     99 int main()
    100 {
    101     int i=5;
    102     Complex c1(1,2),c2(3,4);
    103 
    104 
    105     --c2;
    106     c2.printC(); //输出2+3i
    107 
    108     Complex c3=c2--;
    109     c2.printC(); //输出1+2i
    110     c3.printC(); //输出2+3i
    111 
    112     system("pause");
    113     return 0;
    114 }

    4.C++重载"<<"运算符:

    "<<"运算符的本质是ostream类的对象cout重载的一个函数,我们无法在ostream类里面将"<<"的重载函数添加为类ostream的成员函数,也无法在ostream类里面将"<<"的重载函数声明为ostream类的友元函数,因为我们根本无法得到ostream类的原码。所以只能在Complex类里面将"<<"的重载函数添加为类Complex的成员函数,或者将"<<"的重载函数声明为Complex类的友元函数。如果将"<<"运算符的重载函数写成是类Complex的成员函数,则调用的时候也是不对的。因为"<<"运算符是左结合的,它的重载函数本质上是ostream& operator<<(Complex&)的形式,如果写成类的成员函数形式只能是写在ostream类里面,肯定由cout这个对象来调用,即cout.operator<<(Complex对象)的调用形式,不可能是写在Complex类里面由Complex的类对象来调用(左结合性)。而我们前面提到过,我们无法得到ostream类的源码,无法将重载函数写在sstream类里面,因此,我们做出结论:”<<“运算符重载函数只能是声明为Complex类的友元函数。具体代码如下:

    friend ostream& operator<<(ostream&,Complex&);//在Complex类体里面将operator<<函数声明为类Complex的由原函数

    //operator<<友元函数的实现代码

    ostream& operator<<(ostream& out,Complex& c)
    {
        out<<c.a<<"+"<<c.b<<"i";
        return out;
    }

     //上面的代码中之所以返回ostream&是为了<<可以串联使用。如cout<<c1<<"Hello"<<endl

     当被重载的运算符的左右两侧的操作数类型不一样的时候,最好用友元函数重载运算符,这样无论哪种类型的操作数写在前面,都能调用运算符重载函数。

    5.C++里面不能重载的运算符有5个:

    .(成员访问运算符)      

    .*(成员指针访问运算符)      

     ::(域运算符)    

     sizeof(长度运算符)      

    ?:(条件运算符)

    6.C++里面最好不要重载"&&"和"||"运算符,虽然在语法上它们支持重载,但重载的运算符无法实现原来运算符的短路效果。所谓的短路效果是指:a&&b,若果a表达式是假,则不必判断b表达式,直接判断(a&&b)为假。而重载“&&”运算符后,调用重载后的"&&"运算符本质上是执行a.operator&&(b)函数,它一定是先执行b表达式的,所以无法实现短路效果

  • 相关阅读:
    使用padding值控制控件的隐藏与显示
    首篇 sdk 之 AlertDialog
    eclipse中svn项目重定向地址
    Activity回传值报错:Failure delivering result ResultInfo{who=null,request=7,result = 0,data=null}
    常见字符集&乱码问题
    rhel 6.x 使用 udev scsi rules 配置裸设备
    rsync 同步文件
    debian 8.2 + apt-get + mongodb 3.2 + replica set
    debian 8.2 + apt-get + mongodb 3.2
    oracle virtualbox 扩大虚拟机硬盘
  • 原文地址:https://www.cnblogs.com/jswu-ustc/p/8350146.html
Copyright © 2011-2022 走看看