C++——运算符的重载---以成员函数方式重载---以友元函数方式重载

一、运算符的重载

  1、运算符的重载

  允许把标准运算符(如+ - * /等运算符)应用于自定义数据类型的对象,可以提高程序的可读性,运算符的重载本质上还是函数重载。运算符仅仅是语法上的方便,它是另一种函数调用的方式,只有在设计涉及的代码更容易写,尤其是更容易读的时候才有必要重载。

  2、实现运算符重载的方式

  • 类的成员函数
  • 友元函数(即类外的普通函数)

  3、运算符重载的原则:

  • 不能重载的运算符有5个:  .  .*  ?: ::  sizeof
  • 运算符重载不允许发明新的运算符
  • 不能改变运算符操作对象的个数
  • 运算符被重载后其优先级与结合性不会改变

  4、友元函数与类成员函数的使用场合:

  • 一般情况下,建议一元运算符使用类的成员函数,二元运算符使用友元函数

    • 运算符的操作需要修改类对象的状态,则使用成员函数。如需要做左值操作数的运算符(=,+=,*=,++,--)
    • 运算时,有数与对象的混合运算时,必须使用友元函数
    • 二元运算中,第一个操作数为非对象时,必须使用友元函数。如输入输出运算符<< >>
  • 具体规则如下:

  5.友元函数与类成员函数的参数与返回值

  • 参数:

    • 当参数不会被改变时,一般采用const引用,
  • 返回值:
    • 如果返回值可能出现在=左边,则只能作为左值,返回非const引用
    • 如果返回值只能出现在=右边,则只能作为右值,返回const型值或const型引用
    • 如果返回值既可能出现在=号左边,也可能出现在=右边,则其返回值必须为左值,返回非const引用。




二、使用函数、类成员函数、友元函数分别实现复数+运算符的重载

  1、使用函数实现两个复数相加。示例代码如下:

  •  1 class Complex
     2 {
     3     public:
     4         Complex()
     5         {
     6             real = 0;
     7             imag = 0;
     8         }
     9
    10         Complex Complex_Add(Complex &);
    11
    12     private:
    13         double real;
    14         double imag;
    15 };
    16
    17 Complex Complex :: Complex_Add(Complex &c2)
    18 {
    19     Complex temp;
    20     temp.real = this->real + c2.real;
    21     temp.imag = this->imag + c2.imag;
    22
    23     return temp;
    24 }
    25
    26 int main()
    27 {
    28     Complex c1(3,4),c2(1.2,-4),c3;
    29     c3 = c1.Complex_Add(c2);
    30     return 0;
    31 }
  • 这种调用方式太繁琐而且不直观


  2、使用类成员函数重载运算符+实现复数运算。具体代码如下:

  •  1 class Complex
     2 {
     3     public:
     4         Complex() //无参构造函数
     5         {
     6             real = 0;
     7             imag = 0;
     8         }
     9         Complex(double r, double i) //有参构造函数
    10         {
    11             real  = r;
    12             imag = i;
    13         }
    14         Complex operator + (Complex &c2); //声明重载运算符
    15     private:
    16         double real;
    17         double imag;
    18 };
    19
    20 Complex Complex::operator +(Complex &c2)
    21 {
    22     Complex C;//定义一个C对象是为了能够连续使用+操作符
    23     C.real = real + c2.real;
    24     C.imag = imag + c2.imag;
    25     return C;
    26 }
    27 int main()
    28 {
    29     Complex c1(3,4), c2(5,-10), c3;
    30     c3 = c1 + c2; //运算符+ 用于复数运算
    31     return 0;
    32 }
  • 主函数在执行c1+c2语句时,调用了运算符重载函数operator+()函数
  • 相当于c1.operaor+(c2);


  3、使用友元函数重载运算符+实现复数的相加。具体代码如下:

  •  1 class Complex
     2 {
     3     public:
     4         Complex()
     5         {
     6             real = 0;
     7             imag = 0;
     8         }
     9         Complex(double r, double i)
    10         {
    11             real  = r;
    12             imag = i;
    13         }
    14         friend Complex operator + (Complex &c1, Complex &c2); //声明重载运算符
    15     private:
    16         double real;
    17         double imag;
    18 };
    19
    20 Complex operator +(Complex &c1,Complex &c2)
    21 {    return Complex(c1.real + c2.real, c1.imag + c2.imag);//直接调用复制构造函数
    22 }
    23 int main()
    24 {
    25     Complex c1(3,4), c2(5,-10), c3;
    26     c3 = c1 + c2; //运算符+ 用于复数运算
    27     return 0;
    28 }

    必须是complex的对象才可以相加。如果是实数与complex对象相加,则实数会被默认的构造函数强制转换为虚部为0的复数进行相加。

未完待续!!!!!!!!!!!!!

原文地址:https://www.cnblogs.com/southcyy/p/10260626.html

时间: 2024-10-24 20:17:00

C++——运算符的重载---以成员函数方式重载---以友元函数方式重载的相关文章

为什么 构造函数、内联函数、静态函数和友元函数不能是虚函数

构造函数为什么不能是虚函数 C++ 从存储空间角度,虚函数对应一个指向vtable虚函数表的指针,这大家都知道,可是这个指向vtable的指针其实是存储在对象的内存空间的.问题出来了,如果构造函数是虚的,就需要通过vtable来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数.简单来说就是:虚函数的执行依赖于虚函数表.而虚函数表在构造函数中进行初始化工作,即初始化vptr,让他指向正确的虚函数表.而在构造对象期间,虚函数表还没有被初始化,将无法进行

C++运算符重载(友元函数方式)

我们知道,C++中的运算符重载有两种形式:①重载为类的成员函数(见C++运算符重载(成员函数方式)),②重载为类的友元函数. 当重载友元函数时,将没有隐含的参数this指针.这样,对双目运算符,友元函数有2个参数,对单目运算符,友元函数有一个参数.但是,有些运行符不能重载为友元函数,它们是:=,(),[]和->. 重载为友元函数的运算符重载函数的定义格式如下: [cpp] view plaincopy 一.程序实例 [cpp] view plaincopy 1 //运算符重载:友元函数方式 2

关于友元函数,运算符重载和类的类型转换

一 关于运算符的重载:运算符中有10种是不可重载的:sizeof static_cast<type>. dynamic_cast<type>.* const_cast<type>:: typeid?= reinterpret_cast<type>有4种是只可以在类中重载的:() [] = -> (1)同时在重载时需要有一个参数是用户自己定义的类成员,否则无法使用 (2)运算符的使用方式,及所需参数个数与重载前所需的参数个数相同 重载的格式: retur

C++重载(主要介绍使用友元函数重载)

重载限制 多数C++运算符都可以用下面的方式重载.重载的运算符不必是成员函数,但必须至少有一个操作数是用户自定义的类型.下面详细介绍C++对用户定义的运算符重载的限制. 1 重载后的运算符必须至少有一个操作数是用户自定义的类型,这将防止用户为标准类型重载运算符.因此,不能将减法运算符(-)重载为double值的和,而不是它们的差.虽然这种限制将对创造性有所影响,但可以确保程序正常运行. 2 使用运算符时不能违反运算符原来的句法规则.例如,不能将求模运算符(%)重载成使用一个操作数. 同样,不能修

友元函数实现操作符重载的应用场景-友元函数实现左移右移操作符重载

先定义一个测试类Complex,其中用成员函数的方法重载了+.-.前置++.前置--.后置++.后置--这6个运算符,当然,这6个操作符也可以用友元函数方式重载,但习惯上这些都直接用成员函数方式重载. demo #include <iostream> using namespace std; class Complex { public: Complex(int a = 0, int b = 0) { this->a = a; this->b = b; } ~Complex();

4 C++基础4 类 const函数 转全局函数 返回*this 数组类。友元 函数 类 操作符重载

1,请问类中函数 const修饰的谁? [email protected]:~/c++$ cat main.cpp  #include <iostream> #include <stdlib.h> using namespace std; class A { public: //const的三种写法 //const void fun(int a,int b) //void const fun(int a,int b) //void fun(int a,int b) const vo

关于声明、定义、前向声明、include、循环依赖、普通友元函数、友元类、友元成员函数的总结

做<C++ Primer>(第5版)253页练习题7.3.4有感,故总结之 1 声明 1.1 变量和函数的声明 常见的声明是声明一个变量或函数,一般在头文件.h中声明,例如: pos cursor = 0; // 给定初始值 char get(pos r, pos col) const; 1.2 类的声明 对于一个类,一般是直接在头文件中直接写 class ClassName { ... },这称之为类的定义,然后在类体{...}中又声明或定义了成员变量和成员函数.类的声明是没有类体,只有个类

C++:友元(非成员友元函数、成员友元函数、友元类)

3.8  友元:友元函数和友元类 友元函数 :既可以是不属于任何类的非成员函数,也可以是另一个类的成员函数,统称为友元函数.友元函数不是当前类的成员函数,而是独立于类的外部函数,但它可以访问该类所有的成员,包括私有成员.保护成员和公有成员.在类中声明友元函数时,需在其函数名前加上关键字friend,此声明可以放在公有部分.也可以放在保护和私有部分.友元函数可以定义在类部,也可以定义在类的外部. 3.8.1 将非成员函数声明为友元函数 //1.将非成员函数声明为友元函数 // 例3.33 友元函数

C++友元函数(转)

此文转自C++_友元函数. 1. 引入友元函数原因 在实现类之间数据共享时,减少系统开销,提高效率. 具体来说:为了使其他类的成员函数直接访问该类的私有变量. 即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数. 优点:能够提高效率,表达简单.清晰. 缺点:友元函数破环了封装机制,尽量不使用成员函数,除非不得已的情况下才使用友元函数. 2. 使用友元函数时机 1)运算符重载的某些场合需要使用友元. 2)两个类要共享数据的时候 3. 如何使用友元函数  3.1 友元函数的

C++之友元机制(友元函数和友元类)

一.为什么引入友元机制? 总的来说就是为了让非成员函数即普通函数或其他类可以访问类的私有成员,这确实破坏了类的封装性和数据的隐蔽性,但为什么要这么做呢? (c++ primer:尽管友元被授予从外部访问类的私有部分的权限,但它并不与面向对象的编程思想相悖,相反,他们提高了公有接口的灵活性).要理解这句话,就必须知道友元形成的过程:(任何函数,或者成员函数或者类想成为某个类的友元,这是由这个类来决定的,而不能从外部强加友情) 我们已知道类具有封装和信息隐藏的特性.只有类的成员函数才能访问类的私有成