C++学习27 用全局函数重载运算符

运算符重载函数既可以声明为类的成员函数,也可以声明为所有类之外的全局函数。

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

将运算符重载函数声明为类的成员函数时,二元运算符的参数只有一个,一元运算符不需要参数。之所以少一个参数,是因为这个参数是隐含的。

例如,上节的 complex 类中重载了加法运算符:

complex operator+(const complex & A)const;

当执行:

c3 = c1 + c2;

会被转换为:

c3 = c1.operator+(c2);

通过 this 指针隐式的访问 c1 的成员变量。

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

将运算符重载函数声明为全局函数时,二元操作符就需要两个参数,一元操作符需要一个参数,而且其中必须有一个参数是对象,好让编译器区分这是程序员自定义的运算符,防止程序员修改用于内置类型的运算符的性质。

例如,下面这样是不对的:

int operator + (int a,int b){
    return (a-b);
}

"+"号原来是对两个数相加,现在企图通过重载使它的作用改为两个数相减。 如果允许这样重载的话,那么表达式 4+3 的结果是7还是1呢?显然,这是绝对禁止的。

如果有两个参数,这两个参数可以都是对象,也可以一个是对象,一个是C ++内置类型的数据,如:

complex operator+(int a, complex &c){
    return complex(a+c.real, c.imag);
}

它的作用是使一个整数和一个复数相加。

更改上节的 complex 类,用全局运算符重载函数计算复数的和:

#include <iostream>
using namespace std;
class complex{
private:
    double real;  //实部
    double imag;  //虚部
public:
    complex(): real(0.0), imag(0.0){ }
    complex(double a, double b): real(a), imag(b){ }
    void display()const{ cout<<real<<" + "<<imag<<"i"<<endl; }
    friend complex operator+(const complex &A, const complex &B);  //友元函数
};
//全局运算符重载
complex operator+(const complex &A, const complex &B){
    complex C;
    C.real = A.real + B.real;
    C.imag = A.imag + B.imag;
    return C;
}
int main(){
    complex c1(4.3, 5.8);
    complex c2(2.4, 3.7);
    complex c3;
    c3 = c1 + c2;
    c3.display();
    return 0;
}

因为重载运算符函数要用到 complex 类的私有变量,所以我们将该函数声明为友元函数。当执行:

c3 = c1 + c2;

会被转换为:

c3 = operator+(c1, c2);

最后要说明两点:

  • 只有在极少的情况下才使用既不是类的成员函数也不是友元函数的普通函数,原因是上面提到的,普通函数不能直接访问类的私有成员。
  • 指针操作符“->”、下标操作符“[]”、函数调用操作符“()”和赋值操作符“=”只能以成员函数的形式重载。
时间: 2024-10-05 08:15:28

C++学习27 用全局函数重载运算符的相关文章

从一个二级题来看成员函数重载运算符和友元函数重载运算符

先上题:下列运算符都可以被友元函数重载的是: A)=,+,-,\ B)[],+,(),new C)->,+,*,>> D)<<,>>,+,* 正确答案为D 我们知道,在运算符重载,友元函数运算符重载函数与成员运算符重载函数的区别是:友元函数没有this指针,而成员函数有,因此,在两个操作数的重载中友元函数有两个参数,而成员函数只有一个. 因此,我们可以总结如下: 1.对双目运算符而言,成员函数重载运算符的函数参数表中只有一个参数,而用友元函数重载运算符函数参数表中

C++ 关于重载问题:重载函数/重载运算符问题

老生常谈的问题,N年前仔细做过总结,现在全忘光了: 重载函数: 一定要参数列表不同,名字相同,C++编译器可以根据参数的类型自动调用: void exc(char& a, char& b) { char temp = a; b = a; b = temp; } void exc(int& a, int& b) { int temp = a; a = b; b = temp; } void exc(string& a, string& b) { string

87.重载流式运算符以及外部函数重载运算符

1 #define _CRT_SECURE_NO_WARNINGS 2 #include <iostream> 3 using namespace std; 4 5 class box 6 { 7 private: 8 int x; 9 int y; 10 int z; 11 12 13 public: 14 box() :x(10), y(20), z(30) 15 { 16 17 } 18 19 friend box operator +(const box &box1, cons

调用成员函数重载运算符

#include <iostream> using namespace std; class Complex { private:     int real;     int image; public:     Complex(int real=0,int image=0):real(real),image(image)     {     }     Complex operator+(const Complex &c)     {         return Complex(r

C++语言学习(八)——操作符重载

C++语言学习(八)--操作符重载 一.操作符重载基础 1.操作符重载的语法 通过operator关键字可以定义特殊的函数,operator本质是通过函数重载操作符. Type operator operatorname(const Type p1, const Type p2) { Type ret; return ret; } 2.友元函数重载操作符 可以将操作符重载函数声明为友元函数. #include <iostream> using namespace std; class Comp

c++重载运算符实验定义分数类实现分数间四则运算

实验二           自定义类型的运算 [实验目的] 理解运算符函数与运算符重载方法: 掌握运算符重载为友元函数: [实验内容] 题目: 在C++中,分数不是预先定义的,建立一个分数类,使之具有以下功能:能防止分母为0.当分数不是最简形式时进行约分及分母为负数.用重载运算符完成加法.减法.乘法.除法等四则运算. 源程序代码: #include<iostream> #include<cstdlib> using namespace std; int gcd(int m,int

函数重载基础知识

1 #include<iostream> 2 using namespace std; 3 4 //1 当同一函数名和不同的参数搭配时函数的含义不同 5 void myPrint(int a) 6 { 7 printf("a:%d\n", a); 8 } 9 void myPrint(char *p) 10 { 11 printf("%s\n", p); 12 } 13 void myPrint(int a, int b) 14 { 15 printf(

流插入运算符为什么要被重载为全局函数?

https://www.coursera.org/learn/cpp-chengxu-sheji/lecture/c3tbl/liu-cha-ru-yun-suan-fu-he-liu-ti-qu-yun-suan-fu-de-zhong-zai  笔记 Part 1. 流插入运算符的重载: cout<<5<<endl; cout是在iosream中定义的一个ostream对象 iostream中对“<<”进行了重载.  cout<<5; 即 cout.op

初探C++运算符重载学习笔记&amp;lt;2&amp;gt; 重载为友元函数

初探C++运算符重载学习笔记 在上面那篇博客中,写了将运算符重载为普通函数或类的成员函数这两种情况. 以下的两种情况发生.则我们须要将运算符重载为类的友元函数 <1>成员函数不能满足要求 <2>普通函数又不能訪问类的私有成员时 举例说明: class Complex{ double real, imag; public: Complex(double r, double i):real(r), imag(i){ }; Complex operator+(double r); };