技术好文共享:重载运算符详解

简介: 技术好文共享:重载运算符详解

重载运算符详解


1.概念


运算符的重载,实际是一种特殊的函数重载,必须定义一个函数,并告诉C++编译器,当遇到该运算符时就调用此函数来行使运算符功能。这个函数叫做运算符重载函数(常为类的成员函数)。 用函数的方式实现//代码效果参考:http://hnjlyzjd.com/xl/wz_25182.html

了(+ - / 【】数组 && || 逻辑 等)运算符的重载。根据需求决定重载那些运算符,用到的时候再百度案例即可。

2.运算符重载的基本格式


返回值类型 类名::operator重载的运算符(参数表) { …… }


operator是关键字,它与重载的运算符一起构成函数名。


3.运算符重载的两种方法


二元运算符重载


1.类内重载


#include


using namespace std;


?


class Point{


public:


Point(){};


Point (int x, int y): x(x),y(y) {};


Point operator+(const Point &b){ //类内重载,运算符重载函数作为类的成员函数


Point ret;


ret.x = this->x + b.x;


ret.y = this->y + b.y;


return ret;


}


int x,y;


};


?


int main() {


Point a(2,4),b(5,3);


Point c = a + b; //这里c++编译器会,自动去找 + 运算符的重载函数


cout[ "x :" [ c.x [ endl;


cout["y :" [ c.y [ endl;


}


//代码效果参考:http://hnjlyzjd.com/hw/wz_25180.html

运行结果:x : 7 ? ? y : 7


重点:运算符重载是类内重载时,运算符重载函数作为类的成员函数,以上述代码为例 a + b 相当于 a 对象调用+方法并且传入参数时 b 对象。


2.类外重载(用友元函数的方法实现)


#include


using namespace std;


?


class Point{


public:


Point(){};


Point (int x, int y): x(x),y(y) {};


friend Point operator+(const Point &, const Point &); //声明类的友元函数


int x,y;


};


?


Point operator+(const Point &a,const Point &b){//类外重载,运算符重载函数作为类的友元函数


Point ret;


ret.x = a.x + b.x;


ret.y = a.y + b.y;


return ret;


}


?


int main() {


Point a(2,4),b(5,3);


Point c = a + b;


cout[ "x :" [ c.x [ endl;


cout["y :" [ c.y [ endl;


}


一元运算符重载(注意:返回值当左值得时候,返回的是一个引用)


1.插入运算符重载] and 提取运算符重载[ 以提取运算符重载[为例,cout 是 ostream 类的对象。ostream 类和 cout 都是在头文件 中声明的。ostream 类将[重载为成员函数。


下面我们重载 [ 使用cout输出a对象


#include


using namespace std;


?


class Point{


public:


Point(){};


Point (int x, int y): x(x),y(y) {};


friend ostream &operator[(ostream &out , const Point &a); //因为 [ 是C++提供的类,我们无法访问,只能用友元函数。


private:


int x,y;


};


?


//[ 运算符重载的函数实现 ostream是输入输出流的类


ostream &operator[(ostream &out , const Point &a){


out [ "


( " [ a.x [ ", " [ a.y [ ")";


return out;


}


?


int main() {


?


cout [ c[ endl; //直接输出类会报错,需要上面的 [ 运算符重载


}


输出结果:( 7, 7) 重点:另外应该会有人对ostream &operator[(ostream &out , const Point &a)函数感到疑惑,首先在重载[时,返回值类型是ostream&, 第一个参数也是ostream& 。也就是说,表达式cout[c的返回值仍是 cout,所以cout[c[endl;才能成立。


2.前置运算符重载++ and 后置运算符重载++ 重点:为区别前置和后置运算符,C++编译器要求,需要在后置运算符重载函数中加参数“int”,这个类型在此除了以示区别之外并不代表任何实际含义;如果不加,编译器无法区分是前置++,还是后置++,导致报错。


#include


using namespace std;


?


class Point{


public:


Point(){};


Point (int x, int y): x(x),y(y) {};


friend Point operator+(const Point &, const Point &);


friend ostream &operator[(ostream &out , const Point &a);


Point& operator++(){ //前置++运算符,需要引用返回,不需要参数。返回自增后的值,且返回的是一个左值


this->x ++;


this->y ++;


return this;


}


//const 修饰返回值不能修改


const Point operator++(int){//后置++,不需要引用返回,需要参数区分。返回自增前的值,且返回的是一个右值


Point temp(x,y); //因为后置++,是先使用,后自++,所以这里要保存一个临时值,再++,返回的是临时值。


this->x ++;


this->y ++;


return temp;


}


private:


int x,y;


};


?


Point operator+(const Point &a,const Point &b){


Point ret;


ret.x = a.x + b.x;


ret.y = a.y + b.y;


return ret;


}


?


ostream &operator[(ostream &out , const Point &a){


out [ "


(" [ a.x [ " , " [ a.y [ ")";


return out;


}


?


?


int main() {


Point a(2,4),b(5,3);


Point c = a + b;


cout [ c [ endl;


c++;


cout [ c [ endl;


++c;


cout [ c [ endl;


}


3.=等号运算符重载 C++中,对类对象进行操作时,我们就不能只是简简单单地,对类对象用=进行操作。 当我们没有自己设计等号运算符的重载函数,编译器会自动生成一个浅拷贝的赋值运算符的重载函数。 浅拷贝:只是简单地将一个对象的内存数据赋值给另一个对象,如果这个对象成员变量引用了外部资源时(new),那么这两个对象的成员变量都指向这个空间,当这两个对象生存周期结束时,进行析构,那么就会崩溃,对同一块内存我们delete了两次。


#include


using namespace std;


?


class Name


{


public:


?


//main函数中的问题 Name obj2 = obj1;


//解决方案: 手工的编写拷贝构造函数 使用深copy


Name(const Name& obj)


{


m_len = obj.m_len;


m_p = (char )malloc(m_len + 1);


strcpy(m_p, obj.m_p);


}


?


//等号运算符重载函数


Name& operator=(Name &obj)


{


//1.先释放旧的内存


if (this->m_p != NULL)


{


delete【】 m_p;


m_len = 0;


}


//2.根据obj分配内存大小


this->m_len = obj.m_len;


this->m_p = new char 【m_len+1】; //加1,结束符'\n'。


//3.把obj赋值


strcpy(m_p, obj.m_p); //字符串的拷贝函数


return this;


}


~Name() //析构函数


{


if (m_p != NULL)


{


free(m_p);


m_p = NULL;


m_len = 0;


}


}


protected:


private:


char *m_p ;


int m_len;


};


?


void main()


{


?


Name obj1("abcdefg");


Name obj2 = obj1; //C++编译器提供的 默认的copy构造函数 浅拷贝,需要手工编写构造函数


Name obj3("obj3");


?


obj1 = obj2 = obj3; //调用等号运算符重载


cout["hello..."[endl;


system("pause");


return ;


}

相关文章
|
2月前
|
存储 JavaScript IDE
探索变量世界的奥秘:全面理解与有效避坑
【4月更文挑战第2天】探索编程基础:变量。本文详述变量的定义、作用,如数据存储、信息传递,以及声明与赋值。讨论变量类型(如整型、浮点型)和作用域(全局、局部),并列举常见错误及防范策略,如未声明使用、类型不匹配。最后提出最佳实践,如明确命名、避免冗余和适时复用变量,以提升代码质量。通过本文,深化你对变量的理解,让编程更加得心应手!
45 8
|
9月前
|
Go
Go语言构造函数的力量:初始化和配置的艺术
Go语言构造函数的力量:初始化和配置的艺术
70 0
|
9月前
|
算法 编译器 C++
类与对象知识总结+封闭类+const+this指针 C++程序设计与算法笔记总结(三) 北京大学 郭炜(中)
类与对象知识总结+封闭类+const+this指针 C++程序设计与算法笔记总结(三) 北京大学 郭炜(中)
37 0
|
21天前
|
C++ 索引
C++核心技术要点《运算符重载》
C++核心技术要点《运算符重载》
25 2
|
6天前
|
C语言
技术经验分享:2_成员函数(MemberFunctions)
技术经验分享:2_成员函数(MemberFunctions)
|
5天前
|
Windows
技术好文共享:简单介绍SXS的一些有意思的特性
技术好文共享:简单介绍SXS的一些有意思的特性
|
5天前
|
前端开发
技术好文共享:第二十二webchat(2)
技术好文共享:第二十二webchat(2)
|
5天前
|
存储 自然语言处理 编译器
技术好文共享:程序的基本概念
技术好文共享:程序的基本概念
|
5天前
|
算法 Linux 调度
技术好文共享:详解操作系统中断
技术好文共享:详解操作系统中断
|
9月前
|
存储 算法 编译器
类与对象知识总结+封闭类+const+this指针 C++程序设计与算法笔记总结(三) 北京大学 郭炜(上)
类与对象知识总结+封闭类+const+this指针 C++程序设计与算法笔记总结(三) 北京大学 郭炜(上)
34 0