36.【C/C++ 重载运算符,(全干的无水分)】

简介: 36.【C/C++ 重载运算符,(全干的无水分)】

(一)、什么是运算符重载

运算符重载的方法是定义一个运算符重载函数,也就是说,运算符重载函数是通过定义一个函数来实现的,运算符重载实质上是函数的重载。运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。

(二)、什么是运算符重载函数?

自定义类的赋值运算符重载函数的作用与内置赋值运算符的作用类似,但是要注意的是,它与拷贝构造函数与析构函数一样,要注意深拷贝浅拷贝的问题,在没有深拷贝浅拷贝的情况下,如果没有指定默认的赋值运算符重载函数,那么系统将会自动提供一个赋值运算符重载函数。

(三)、运算符重载的基本作用

**所谓重载,就是赋予新的含义。**实际上我们在前期的学习过程中已经不知不觉使用了运算符重载,如"<<“和”>>“本来是c++的位移运算符,但是却可以用来输入与输出,这是因为c++系统对”<<“和”>>"运算符进行了重载,用户在不同的场合下使用它们,作用是不同的。

(四)、运算符重载的格式

函数类型 operator 运算符名称(形参列表)

(五)、运算符重载的方法

函数类型 operator 运算符名称(形参列表)

在上面的格式中,operator是c++的关键字,是专门用于定义重载运算符的函数的,运算符名称就是c++已经有的运算符。注意:函数名是由operator和运算符组成

(六)、运算符重载的规则

1.c++不允许用户自己定义新的运算符,只能对已经有的运算符进行重载。

2.c++允许重载的运算符

双目关系运算符:+,-,,/,%
关系运算符:==,!=,<,>,<=,>=,
逻辑运算符:||,&&,!
单目运算符:+,-,指针,&
自增自减运算符:++,–
位运算符:|,&,~,^,<<,>>
赋值运算符:=,+=,-=,=,/=,%=,&=,|=,^=,<<=,>>=
空间申请与释放:new,delete,new[],delete[]
其他运算符:()函数调用,->,->,逗号,[]下标

c++中不能重载的运算符有五个

.(成员访问运算符),(成员指针访问运算符),::(域运算符),sizeof(长度运算符),?:(条件运算符)

3.重载不能改变运算符运算对象的个数

4.重载不能改变运算符的优先级

5.重载不能改变运算符的结合性

6.重载运算符的函数不能有默认的参数

7.重载的运算符必须和用户定义的自定义类型的对象一起使用,** 其参数至少应有一个使类对象 或类对象的引用 ** 也就是说,参数不能全部使c++的标志类型,以防止用户修改用于标准运算符的性质。

8.用于类对象的运算符一般必须重载,但是有两个例外,运算符“=”和运算符“&”。“=”可以用于每个类对象,这是因为系统已经为每一个新声明的类重载了赋值运算符,它的作用是逐个复制类对象的成员。&也不必重载,它能返回对象在内存中的地址。以上这些规则是很容易理解的,不必死记。

(七)、成员运算符重载和友元运算符重载

7.1在双目与单目中

(1)对双目运算符而言,成员运算符重载函数参数表中含有一个参数,而友元运算符重载函数参数表中含有两个参数,对单目运算符而言,成员运算符重载函数参数表中没有参数而友元运算符重载函数参数表中含有两个参数。

(2)双目运算符一般可以被重载为友元运算符重载函数或成员运算符重载函数,但有一种情况,必须使用友元函数.

7.2必须声明为成员和友元的运算符

1.c++规定,赋值运算符=,下标运算符1,函数调用运算符(),成员运算符->必须作为成员函数重载

2.流插入运算符“<<”和流提取运算符“>>”,类型转换运算符函数不能作为类的成员函数,只能作为友元函数。

3.一般将单目运算符和复合运算符重载为成员函数。

4.一般将双目运算符重载为友元函数。

(八)、实战经典项目

1.单目运算符(-obj,++obj,obj++,obj–,!obj)

1.1重载负数运算符
代码展示:
#include  <iostream>
using namespace std;
class Distance
{
private:
  int feet;
  int inches;
public:
  Distance() { feet = 0; inches = 0; }  //赋值为0
  Distance(int f, int i) { feet = f; inches = i; }   //构造函数
  void showdistace()   //显示距离
  {
    cout << "f:" << feet << ",i:" << inches << endl;
  }
  Distance operator-()
  {
    feet = -feet;
    inches = -inches;
    return *this;    //return Disrance(feet,inches)
  }
};
int main()
{
  Distance d1(1, 10), d(-5, 110);
  -d1;
  d1.showdistace();
  - d;
  d.showdistace();
  return 0;  
}
效果展示:

2.双目运算符(+,-,*,/)

2.1重载加法运算

代码展示:
#include  <iostream>
using namespace std;
class Box
{
private:
  double length;
  double wideth;
  double height;
public:
  Box() { length = 0; wideth = 0; height = 0; }
  Box(int a, int b, int c)
  {
    length = a;
    wideth = b;
    height = c;
  }
  double  show()
  {
    return length * wideth * height;
  }
  //重载运算符+,用于把两个B0X对象加起来
  Box operator+(const Box& b)
  {
    Box box;
    box.length = this->length + b.length;
    box.wideth = this->wideth + b.wideth;
    box.height = this->height + b.height;
    return box;    //不能return *this
  }
};
int main()
{
  Box b(3, 4, 5);
  Box b1(4, 5, 6);
  cout << b.show() << endl;
  cout << b1.show() << endl;
  Box b3;
  b3 = b1.operator+(b);
  cout << b3.show() << endl;
}
效果展示:

2.2重载加法(复数)

代码展示:
#include <iostream>
using namespace std;
class Complex
{
private:
 double real;
 double imag;
public:
 Complex() {}
 Complex(double r, double i)
 {
  real = r;
  imag = i;
 }
 Complex operator+(Complex& c1)
 {
  Complex c;
  c.real = real + c1.real;
  c.imag = imag + c1.imag;
  return c;
 }
 void show()
 {
  cout << "(" << real << "," << imag << ")" << endl;
 }
};
int main()
{
 Complex c(3, 4), c1(5, 5), c2;
 c.show();
 c1.show();
 c2 = c1.operator+(c);
 c2 = c + c1;
 c2.show();
 c2.show();
}
效果展示:

3.关系运算符重载(<,>,<=.>=.==)

3.1重载小于符号(<)

代码展示:
#include  <iostream>
using namespace std;
class Rect
{
private:
  double width;
  double height;
public:
  Rect(double a, double b)
  {
    width = a;
    height = b;
  }
  double area()
  {
    return width * height;
  }
  //重载小于运算符,按照面积比大小
  bool operator<(Rect& that)      // 不能用Rect
  {
    return this->area() < that.area();
  }
};
int main()
{
  Rect r1(3, 4), r2(4, 5);
  cout << r1.area() << endl;
  cout << r2.area() << endl;
  if (r1 < r2)
  {
    cout << "r2大" << endl;
  }
  else
    cout << "r1大" << endl;
  return 0;
}
效果展示:

4.输入/输出运算符重载(<<.>>)

可以把运算符重载函数声明为类的友元函数,这样就可以不用创建对象而直接调用函数.

4.1两个一起用(<< .>>)

1、ostream后面的out是可以换的,这里换成什么,后面的函数体就要换成什么,比如说这里改为ostream&output,那么后面的函数体就要都变成output<<obj.item1

代码展示:
#include  <iostream>
using namespace std;
class Rect
{
private:
  double width;
  double height;
public:
  Rect() { width = 0; height = 0; }
  Rect(double a, double b)
  {
    width = a;
    height = b;
  }
  double area()
  {
    return width * height;
  }
  //重载小于运算符,按照面积比大小
  friend ostream& operator<<(ostream& output, Rect& r)   //固定格式
  {
    output << "width" << r.width << endl;
    output << "height" << r.height << endl;
    output << "area" << r.area() << endl;
    return output;           //返回流的引用
  }
  friend istream& operator>>(istream& input, Rect& r)
  {
    input >> r.width >> r.height;
    return input;           //返回流的引用
  }
};
int main()
{
  Rect r1(3.0, 4.0), r2(6.0, 8.0),r3;
  cin >> r3;
  cout << r1 << endl;
  cout << r2 << endl;
  cout << r3 << endl;
}
效果展示:

5.一元运算符(++、–)

4.1.自增自减运算

代码展示
#include <iostream>
using namespace std;
class Time
{
private:
  int minuate;
  int second;
public:
  Time() { minuate = 0; second = 0; }
  Time(int m, int s)
  {
    minuate = m; second = s;
  }
  void display()
  {
    cout << minuate << " : " << second << endl;
  }
  //前缀++
  Time operator++()
  {
    second++;
    if (second >= 60)
    {
      minuate++;
      second = 0;
    }
    return *this;// Time(minuate, second);
  }
  //后缀++
  Time operator++(int)
  {
    Time t(minuate, second);   //保存原始数据
    second++;    //对象加1;
    if (second >= 60)
    {
      minuate++;
      second = 0;
    }
    return t;  //返回旧的原始值
  }
};
int main()
{
  Time t1(12, 58), t2(0, 45);
  t1.display();
  (++t1).display();
  (++t1).display();
  t2.display();
  (t2++).display();
  (t2++).display();
  return 0;
}
效果展示:


相关文章
|
1月前
|
C++
【C++基础】运算符详解
这篇文章详细解释了C++中运算符的用法,包括算术运算符、赋值运算符、比较运算符和逻辑运算符,以及它们在表达式中的作用和示例。
22 2
|
1月前
|
C++
C++(十九)new/delete 重载
本文介绍了C++中`operator new/delete`重载的使用方法,并通过示例代码展示了如何自定义内存分配与释放的行为。重载`new`和`delete`可以实现内存的精细控制,而`new[]`和`delete[]`则用于处理数组的内存管理。不当使用可能导致内存泄漏或错误释放。
|
2月前
|
C++
c++学习笔记02 运算符
C++学习笔记,介绍了C++中的运算符,包括基本的加减乘除、求模、前后置递增递减、赋值运算符、比较运算符和逻辑运算符的使用及其注意事项。
37 6
|
3月前
|
NoSQL 编译器 Redis
c++开发redis module问题之如果Redis加载了多个C++编写的模块,并且它们都重载了operator new,会有什么影响
c++开发redis module问题之如果Redis加载了多个C++编写的模块,并且它们都重载了operator new,会有什么影响
|
3月前
|
存储 C++
【C++】string类的使用③(非成员函数重载Non-member function overloads)
这篇文章探讨了C++中`std::string`的`replace`和`swap`函数以及非成员函数重载。`replace`提供了多种方式替换字符串中的部分内容,包括使用字符串、子串、字符、字符数组和填充字符。`swap`函数用于交换两个`string`对象的内容,成员函数版本效率更高。非成员函数重载包括`operator+`实现字符串连接,关系运算符(如`==`, `&lt;`等)用于比较字符串,以及`swap`非成员函数。此外,还介绍了`getline`函数,用于按指定分隔符从输入流中读取字符串。文章强调了非成员函数在特定情况下的作用,并给出了多个示例代码。
|
3月前
|
NoSQL Redis C++
c++开发redis module问题之避免多个C++模块之间因重载operator new而产生的冲突,如何解决
c++开发redis module问题之避免多个C++模块之间因重载operator new而产生的冲突,如何解决
|
4月前
|
C++
C++之运算符
C++之运算符
|
4月前
|
安全 程序员 C++
C++一分钟之-重载运算符
【6月更文挑战第21天】C++的运算符重载让程序员能为自定义类型定制运算符行为,增强代码表达力。但要注意清晰性、优先级和返回类型。遵循运算符原有意义,充分测试,并用注释解释非直观设计。示例展示了如何为复数类重载`+`运算符。避免重载内置类型,注意结合性,且慎用隐式转换。重载应提升可读性而非复杂化代码。
43 2
|
4月前
|
C++
C++一分钟之-理解C++的运算符与表达式
【6月更文挑战第18C++的运算符和表达式构成了编程的基础,涉及数学计算、逻辑判断、对象操作和内存管理。算术、关系、逻辑、位、赋值运算符各有用途,如`+`、`-`做加减,`==`、`!=`做比较。理解运算符优先级和结合律至关重要。常见错误包括优先级混淆、整数除法截断、逻辑运算符误用和位运算误解。解决策略包括明确优先级、确保浮点数除法、正确使用逻辑运算符和谨慎进行位运算。通过实例代码学习,如 `(a &gt; b) ? &quot;greater&quot; : &quot;not greater&quot;`,能够帮助更好地理解和应用这些概念。掌握这些基础知识是编写高效、清晰C++代码的关键。
34 3