首页 > 编程语言 >8.4 C++ 运算符重载

8.4 C++ 运算符重载

时间:2023-10-21 15:12:08浏览次数:35  
标签:8.4 int C++ 运算符 Student 重载 ptr name

C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存等底层资源,对于初学者来说可能会有一定的难度。

实现函数重载: 函数重载是C++语言区别于C语言的重要特性,重载就是定义名称相同但符号或后面参数不同的函数,当重载时,编译器会偷偷在相同函数名的前面加上_func关键字字段,以此来实现重载后函数名不重复,通过编译检查.

#include <iostream>

using namespace std;

int func(int x) { return x; }

int func(int x, int y) { return x + y; }

double func(double x, double y) { return x + y; }

int main(int argc, char *argv[])
{
  int ret1 = func(10);
  int ret2 = func(100, 200);
  double ret3 = func(10.5, 20.4);

  cout << ret1 << ret2 << ret3 << endl;

  system("pause");
  return 0;
}

重载与仿函数: 仿函数就是伪函数,一般情况下仿函数需要配合()重载小括号,来实现类似函数调用一样的语法.

#include <iostream>
#include <string>

using namespace std;

class MyPrint
{
public: void operator()(string text)
  {
    cout << text << endl;
  }
};

class MyAdd
{
public: int operator()(int x, int y)
  {
      return x + y;
  }
};

int main(int argc, char *argv[])
{
  MyPrint print;

  print("hello lyshark");              // 使用仿函数
  cout << MyAdd()(100, 200) << endl;   // 匿名仿函数

  system("pause");
  return 0;
}

重载加号运算符: 重载加号运算符,类p3 = p1 + p2重载后等于p3.m_x = p1.m_x + p2.m_x两个数据成员相加.

#include <iostream>
#include <string>

using namespace std;

class Person
{
public:
  int m_x;
  int m_y;

public:
  Person(){};
  Person(int x, int y) :m_x(x), m_y(y) {}

  // 加号运算符重载,这里其实是二元,因为隐藏了一个this指针.
  Person operator + (Person &p)
  {
    Person tmp;
    tmp.m_x = this->m_x + p.m_x;
    tmp.m_y = this->m_y + p.m_y;
    return tmp;
  }
};

int main(int argc, char *argv[])
{
  Person p1(10, 40);
  Person p2(20, 90);

  // 此处相当于 p1(10) + p2(20) / p1(40) + p2(90)
  Person p3 = p1 + p2;
  cout << "p3 m_x = > " << p3.m_x << endl;
  cout << "p3 m_y = > " << p3.m_y << endl;

  system("pause");
  return 0;
}

重载全局函数: 重载运算符可以定义在一个类的内部,也可以定义在类外,定义在类外的则属于全局重载函数.

#include <iostream>

using namespace std;

class Person
{
public:
  int m_x;
  int m_y;

public:
  Person(){};
  Person(int x, int y) :m_x(x), m_y(y) {}
};

// 全局函数实现运算符重载,这个就属于二元运算符重载
Person operator +(Person &p1, Person &p2)
{
  Person tmp;
  tmp.m_x = p1.m_x + p2.m_x;
  tmp.m_y = p1.m_y + p2.m_y;
  return tmp;
}

int main(int argc, char *argv[])
{
  Person p1(10, 30);
  Person p2(20, 50);

  Person p3 = p1 + p2;
  cout << "p3 m_x = > " << p3.m_x << endl;
  cout << "p3 m_y = > " << p3.m_y << endl;

  system("pause");
  return 0;
}

重载左移运算符: 使用<<重载左移运算符,让cout直接输出两个变量,重载左移运算符不可以写成成员函数.

#include <iostream>
#include <string>

using namespace std;

class Person
{
  friend ostream& operator<<(ostream &cout, Person &ptr);
private:
  int m_x;
  int m_y;

public:
  Person(){};
  Person(int x, int y) :m_x(x), m_y(y) {}
};

ostream& operator << (ostream &cout, Person &ptr)
{
  cout << "m_x = " << ptr.m_x << " ----> " << "m_y = " << ptr.m_y << endl;
  return cout;
}

int main(int argc, char *argv[])
{
  Person p1(10, 30);
  Person p2(20, 10);

  cout << p1 << endl;
  cout << p2 << endl;

  system("pause");
  return 0;
}

重载自增/自减运算符: 自增运算符有两种形式第一种是前置自增运算符,这一种需要定义为MyInteger& operator ++ (),而后自增运算符则需要增加一个int占位符MyInteger operator ++ (int)这样编译器才会分得出来是重载前还是后.

#include <iostream>
#include <string>

using namespace std;

class MyInteger
{
  friend ostream& operator<<(ostream& cout, MyInteger & myInt);

public:
  int m_count;
public:
  MyInteger() { m_count = 0; }

  // 重载前置 ++x 运算符
  MyInteger& operator ++ ()
  {
    this->m_count++;
    return *this;
  }
  // 重载后置 x++ 运算符,为了区分前后置,需要在参数后面增加一个int占位符
  // 此时编译器才会认为我们需要使用后置重载运算符了
  MyInteger operator ++ (int)
  {
    MyInteger tmp = *this;
    m_count++;
    return tmp;
  }
};

ostream& operator<<(ostream& cout, MyInteger & myInt)
{
  cout << myInt.m_count;
  return cout;
}

int main(int argc, char *argv[])
{
  MyInteger myInt;

  cout << ++myInt << endl;
  cout << myInt++ << endl;

  cout << ++(++myInt) << endl;

  system("pause");
  return 0;
}

重载指针运算符(智能指针): 智能指正用来托管自定义的对象,让对象可以自动的释放数据,当我们使用一个对象结束以后,无需手动释放堆空间,智能指针会帮助我们完成这个过程.

#include <iostream>
#include <string>

using namespace std;

class Student
{
public:
  char *m_name;
  int m_age;

public:
  Student(char *name, int age)
  {
    this->m_name = name;
    this->m_age = age;
  }
  void Print()
  {
    cout << "Name: " << this->m_name << endl;
    cout << "Age: " << this->m_age << endl;
  }
};

// 定义智能指针,用于自动释放对象所占用的空间
class Smart_Pointer
{
private:
  Student *ptr;
public:
  // 先来执行构造函数,将传入的指针复制到内部
  Smart_Pointer(Student *ptr)
  { this->ptr = ptr; }

  // 重载运算符 -> 让智能指针能够直接指向Student
  Student * operator -> ()
  { return this->ptr; }

  // 重载运算符 *
  Student & operator * ()
  { return *this->ptr; }

  // 定义析构函数,这是智能指针的关键部分,对象会被自动释放
  ~Smart_Pointer()
  {
    if (this->ptr != NULL)
    {
      delete this->ptr;
      this->ptr = NULL;
    }
  }
};

int main(int argc, char *argv[])
{
  // 手动释放的案例:平常的使用方式
  Student *stu = new Student("lyshark", 10);
  stu->Print();
  delete stu;

  // 使用智能指针:则无需考虑释放的问题
  Smart_Pointer ptr(new Student("lyshark", 10));
  ptr->Print();
  (*ptr).Print();

  system("pause");
  return 0;
}

重载赋值运算符: 我们将等于号进行重载,实现对类中数据成员的赋值拷贝.

#include <iostream>
#include <string>

using namespace std;

class Student
{
public:
  int m_uid;
  char *m_name;
public:
  Student(int uid, char *name)
  {
    this->m_uid = uid;
    this->m_name = new char[strlen(name) + 1];
    strcpy(this->m_name, name);
  }
  // 重载 = 实现类数据成员的赋值运算
  Student& operator = (const Student &ptr)
  {
    // 先来判断原来的堆区是否有内容,如果有则先来释放
    if (this->m_name != NULL)
    {
      this->m_uid = 0;
      delete[] this->m_name;
      this->m_name = NULL;
    }
    // 否则,我们直接开辟空间完成内存拷贝
    this->m_name = new char[strlen(ptr.m_name) + 1];
    strcpy(this->m_name, ptr.m_name);
    this->m_uid = ptr.m_uid;

    return *this;
  }
  // 析构函数,则需要释放内存
  ~Student()
  {
    if (this->m_name != NULL)
    {
      this->m_uid = 0;
      delete[] this->m_name;
      this->m_name = NULL;
    }
  }
};

int main(int argc, char *argv[])
{
  Student stu1(1,"lyshark");
  Student stu2(2, "admin");
  Student stu3(0, "");

  stu3 = stu2 = stu1;

  cout << stu3.m_name << endl;
  cout << stu2.m_name << endl;
  cout << stu1.m_name << endl;

  system("pause");
  return 0;
}

重载关系运算符: 重载关系运算符则可以实现两个类对象的直接对比.

#include <iostream>
#include <string>

using namespace std;

class Student
{
public:
  int m_uid;
  char * m_name;

public:
  Student(int uid,char *name)
  {
    this->m_uid = uid;
    this->m_name = name;
  }

  bool operator == (Student &ptr)
  {
    if (this->m_uid == ptr.m_uid && this->m_name == ptr.m_name)
      return true;
    return false;
  }
  bool operator != (Student &ptr)
  {
    if (this->m_uid != ptr.m_uid && this->m_name != ptr.m_name)
      return true;
    return false;
  }
};

int main(int argc, char *argv[])
{
  Student stu1(1, "lyshark");
  Student stu2(1, "lyshark");
  Student stu3(2, "admin");

  if (stu1 == stu2)
    cout << "stu1 = stu2" << endl;

  if (stu1 != stu3)
    cout << "stu1 != stu3" << endl;

  system("pause");
  return 0;
}

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/d874bf7f.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

标签:8.4,int,C++,运算符,Student,重载,ptr,name
From: https://www.cnblogs.com/LyShark/p/17778999.html

相关文章

  • 8.5 C++ 继承与多态
    C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存......
  • JavaScript 运算符
     算术运算符简表运算符描述例子x的运算结果y的运算结果在线实例(来源runoob.com)+加法x=y+275实例>>-减法x=y-235实例>>*乘法x=y*2105实例>>/除法x=y/22.55实例>>%取余数(模)x=y%215实例>>++ 自......
  • C++函数如何具有多个返回值?
      本文介绍在C++语言中,使用一个函数,并返回两个及以上、同类型或不同类型的返回值的具体方法。  对于C++语言而言,其不能像Python等语言一样在一个函数中返回多个返回值;但是我们也会经常遇到需要返回两个甚至更多个值的需求。针对这种情况,我们可以通过pair、tuple(元组)等数据结......
  • C语言 运算符
    大家好,欢迎来大家参考我的文章,学习任何一门语言都非常需要强大的实践能力,理论知识,学习C语言是个很漫长的过程,学习到后面还需要算法数据结构的支撑,再到后面大家就可以尝试一些比赛:蓝桥杯...检验自己的实力,这是我的第二篇文章,我呢一直在以白话文方式,少使用编程语言术语,让更好理解C语......
  • C++语言基础纲要
    1、C++程序的结构2、输出语句cout<<5<<"hello"<<endl;3、输入语句cin>>a;4、变量 三要素:类型变量名值 命名规则 使用原则5、常量const关键字修饰6、基本数据类型 整型 int 3588 浮点型 double双精度float单精度 字符型 char'A''8' 布尔类型 boolt......
  • C++数据类型:
    C++数据类型:一:基本数据类型类型关键字布尔型bool字符型char整型int浮点型float双浮点型double无类型void宽字符型wchar_t其实wchar_t是这样来的:typedefshortintwchar_t;所以wchar_t实际上的空间是和shortint一样。一些基本......
  • C++学习笔记Day2
    关于String对象的一些事1.string对象来源于C++标准库<string>,表示一种可变长的字符序列,定义在命名空间std之中。2.string对象无初始值默认为空字符串。3.若是使用等号对string变量进行初始化,属于拷贝初始化,不使用等号,如strings6("hiya");strings7{"11123"};strings8(10,"c......
  • 栈实现算术优先级运算c++
    #include<stdlib.h>#include<stdio.h>#include<iostream>usingnamespacestd;#defineSTACK_INIT_SIZE100//栈初始开辟空间大小#defineSTACK_INCREMENT10//栈追加空间大小//优先级数组,2表示top>c,1表示top<c,0表示top=c,-1表示错误intprior[7][7]={{2,2,......
  • C++ Primer 中文版(第 5 版)pdf电子版 C++ Primer, 5th Edition
    C++Primer中文版(第5版)pdf电子版C++Primer,5thEdition作者:[美]StanleyB.Lippman/[美]JoséeLajoie/[美]BarbaraE.Moo原作名:C++Primer,5thEdition......
  • C++类型转换
    C++类型转换1.const_castconst_cast可以将const转换成非const,也可以将非const转换成const。需要注意的是const_cast只能用于改变指针或者引用的底层const。底层const和顶层const首先要弄清楚const修饰的到底是谁,用顶层表示指针本身是个常量(指针常量),底层表示指针所指向的对......