C++运算符重载

简介: 📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段>——目标Windows,MySQL,Qt,数据结构与算法,Linux,多线程,会持续分享学习成果和小项目的📖作者主页:热爱编程的小K📖专栏链接:c++🎉欢迎各位→点赞👏 + 收藏💞 + 留言🔔​💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🐾————————————————版权声明:本文为CSDN博主「热爱编程的小K」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_721574

204401932f51495282608906ff1dce1c.png310d0db40c4d4ffb862b9ec6badddea8.png

204401932f51495282608906ff1dce1c.png

目录

一、运算符重载基础

c++运算符重载是赋予运算符具有操作对象的功能

对于c++运算符重载的本质就是函数调用,所以运算符重载函数如何编写最>为重要

函数返回值当前运算符运算介绍后产物类型,int a,int b,a+b返回int类型

函数名:operator和运算符组成函数名

函数参数

运算符重载函数是类中成员函数:函数参数等于操作数-1

运算符重载函数是友元函数:函数参数等于操作数

**函数体:**写运算符的实际想要的运算

c++类中存在一个赋值的重载函数(默认)

#include <iostream>

using namespace std;

class MM

{

public:

MM(int i,int j):i(i),j(j){}

void print()

{

 cout<<this->i<<"\t"<<this->j<<endl;

}

MM operator+(MM& mm)

{

 return MM(this->i+mm.i,this->j+mm.j);

}

friend void operator+=(MM&mm1,MM&mm2)     //要修改数据,传入引用

{

 mm1.i+=mm2.i;

 mm1.j+=mm2.j;

}

protected:

int i;

int j;

};

int main(int argc, char** argv)  

{

MM mm1(1,2);

MM mm2(5,8);

MM mm3=mm1+mm2;

mm3.print();

MM mm4=mm1.operator+(mm2);  //显示调用

mm4.print();

 

//友元重载

mm1+=mm2;

mm1.print();

operator+=(mm3,mm2);     //显示调用

mm3.print();

}

二、c++特殊运算符重载

1. .= () -> [] 只能重载为类成员函数

2. 运算符重载必须存在至少一个自定义类型才能重载

3. . .* ?: :: 不能被重载

4. c++只允许重载已有运算符,不能无中生有

5. 习惯行为:单目运算符采用类的成员函数重载,双目运算符采用友元重载

1.++和–运算符的重载

  • 对于++和–重载,通过增加无用参数(int)标识为后置运算

#include<iostream>

#include<string>

using namespace std;

class MM

{

public:

MM(string name="",int money=0):name(name),money(money){}

MM operator++()   //前置

{

 this->money++;

 return *this;

}

MM operator++(int)          //后置

{

 return MM(this->name,this->money++);

}

void print()

{

 cout<<this->money<<"\t"<<this->name<<endl;

}

protected:

string name;

int money;

};

int main()

{

MM mm1("king",100);

MM mm2=mm1++;

mm2.print();

MM mm3=++mm2;

mm3.print();

}

2.c++流对象重载

  • cout本质是一个类的对象:ostream,cin本质也是一个类的对象:istream
  • 流重载必须要用友元方式重载
  • 流重载尽量使用引用类型———————————————

#include<iostream>

#include<string>

using namespace std;

class MM

{

public:

MM(string name="",int money=0):name(name),money(money){}

void print()

{

 cout<<this->money<<"\t"<<this->name<<endl;

}

friend ostream& operator<<(ostream& out,MM& object);

friend istream& operator>>(istream& in,MM& object);

protected:

string name;

int money;

};

ostream& operator<<(ostream& out,MM& object)

{

out<<object.name<<"\t"<<object.money<<endl;

return out;

}

istream& operator>>(istream& in,MM& object)

{

cout<<"请输入info:"<<endl;

in>>object.name>>object.money;

return in;

}

int main()

{

MM mm1("king",100);

cin>>mm1;

cout<<mm1<<endl;

}

3.c++文本重载

  • 所谓文本重载,就是重载后缀,固定写法
  • 函数参数:unsigned long long(一定是)
  • 函数名:operator""要重载的后缀——>一般重载后缀采用下划线系列
  • 一个运算符或者一个后缀只能重载被重载一次

#include<iostream>

#include<string>

using namespace std;

unsigned long long operator"" _h(unsigned long long num)

{

return num*3600;

}

unsigned long long operator"" _min(unsigned long long num)

{

return num*60;

}

unsigned long long operator"" _s(unsigned long long num)

{

return num;

}

int main()

{

cout<<1_h+3_min+2_s<<endl;

return 0;

}

4.c++operator实现隐式转换

  • 所谓隐式转换就是可以让对象直接赋值给普通对象
  • 模板
  • operator 隐式转换的类型()

{

   return 数据;

}

#include<iostream>

#include<string>

using namespace std;

class MM

{

public:

MM(string name="",int money=0):name(name),money(money){}

void print()

{

 cout<<this->money<<"\t"<<this->name<<endl;

}

//隐式转换----->便捷获取数据成员的接口

operator int()

{

 return this->money;

}

operator string()

{

 return this->name;

}

protected:

string name;

int money;

};

int main()

{

MM mm("king",89);

int money=mm;

string name=mm;

cout<<money<<"\t"<<name<<endl;

}

三、运算符的应用场景

1.迭代器实现

  • 让对象模拟指针的行为
  • 模板
  • #include<iostream>

#include<string>

using namespace std;

int main()

{

string king="King word!";

string::iterator iter;

for(iter=king.begin();iter!=king.end();iter++)

{

 cout<<*iter<<" ";

}

cout<<endl;

}

#include<iostream>

#include<string>

using namespace std;

struct Node

{

int data;

Node* next;

Node(int data=0):data(data),next(nullptr){}

};

class List

{

public:

void push_front(int data)

{

 Node* newNode=new Node(data);

 if(curSize==0)

  tailNode=newNode;

 else

  newNode->next=frontNode;

 frontNode=newNode;

 curSize++;

}

class iterator

{

public:

 iterator(Node* pmove=nullptr):pmove(pmove){}

 iterator operator++(int)

 {

  return iterator(pmove=pmove->next);

 }

 bool operator!=(iterator&& object) const

 {

  return this->pmove!=object.pmove;

 }

 int operator*()

 {

  return pmove->data;

 }

protected:

 Node* pmove;

};

protected:

Node* frontNode=nullptr;

Node* tailNode=nullptr;

int curSize=0;

public:

iterator begin()

{

 return iterator(frontNode);

}

iterator end()

{

 return iterator(nullptr);

}

};

int main()

{

List list;

for(int i=0;i<=10;i++)

{

 list.push_front(i+1);

}

List::iterator iter;

for(iter=list.begin();iter!=list.end();iter++)

{

 cout<<*iter<<" ";

}

return 0;

}

2.函数包装器

  • 把函数指针包装成一个对象

#include<iostream>

#include<string>

using namespace std;

class Func

{

using Fun=void(*)();

public:

Func(Fun pf):pf(pf){}

void operator()()

{

 pf();

}

protected:

Fun pf;

};

void print()

{

cout<<"我是函数包装器"<<endl;

}

int main()

{

Func x(print);

x();                    //通过对象调用函数

return 0;

}

3.智能指针

  • 可以实现内存的自动申请与释放
  • #include<iostream>

#include<string>

using namespace std;

class King

{

public:

King(int* ptr):ptr(ptr){}

~King()

{

 if(ptr!=nullptr)

 {

  delete ptr;

  ptr=nullptr;

 }

}

int* operator->()

{

 return this->ptr;

}

int operator*()

{

 return *this->ptr;

}

protected:

int *ptr;

};

int main()

{

King k(new int(9999));

cout<<*k<<endl;         //通过对象访问数据

return 0;

}

  • 版权声明:本文为CSDN博主「热爱编程的小K」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_72157449/article/details/128664136

相关文章
|
6月前
|
编译器 C++
C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)
C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)
53 1
|
7月前
|
程序员 编译器 C++
C++中的运算符重载(Operator Overloading)
C++中的运算符重载(Operator Overloading)
60 1
|
3月前
|
C++
C++(十五) 运算符重载
C++中的运算符重载允许对已有运算符的功能进行重新定义,从而扩展语言功能、简化代码并提升效率。重载遵循特定语法,如 `friend 类名 operator 运算符(参数)`。重载时需注意不可新增或改变运算符数量、语义、优先级、结合性和返回类型。常见示例包括双目运算符 `+=` 和单目运算符 `-` 及 `++`。输入输出流运算符 `&lt;&lt;` 和 `&gt;&gt;` 也可重载。部分运算符只能作为成员函数重载。
|
6月前
|
存储 编译器 C++
【C++】:拷贝构造函数和赋值运算符重载
【C++】:拷贝构造函数和赋值运算符重载
30 1
|
6月前
|
C++ 索引
C++核心技术要点《运算符重载》
C++核心技术要点《运算符重载》
54 2
|
5月前
|
自然语言处理 程序员 C++
C++基础知识(五:运算符重载)
运算符重载是C++中的一项强大特性,它允许程序员为自定义类型(如类或结构体)重新定义标准运算符的行为,使得这些运算符能够适用于自定义类型的操作。这样做可以增强代码的可读性和表达力,使得代码更接近自然语言,同时保持了面向对象编程的封装性。
|
5月前
|
Java 程序员 C++
|
5月前
|
编译器 C++
【C++】详解运算符重载,赋值运算符重载,++运算符重载
【C++】详解运算符重载,赋值运算符重载,++运算符重载
|
6月前
|
编译器 C++
【C++】类和对象③(类的默认成员函数:赋值运算符重载)
在C++中,运算符重载允许为用户定义的类型扩展运算符功能,但不能创建新运算符如`operator@`。重载的运算符必须至少有一个类类型参数,且不能改变内置类型运算符的含义。`.*::sizeof?`不可重载。赋值运算符`=`通常作为成员函数重载,确保封装性,如`Date`类的`operator==`。赋值运算符应返回引用并检查自我赋值。当未显式重载时,编译器提供默认实现,但这可能不足以处理资源管理。拷贝构造和赋值运算符在对象复制中有不同用途,需根据类需求定制实现。正确实现它们对避免数据错误和内存问题至关重要。接下来将探讨更多操作符重载和默认成员函数。
|
7月前
|
程序员 C++
C++程序中的运算符重载
C++程序中的运算符重载
45 2