欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

复习笔记(六)——C++运算符重载(难点)

发布时间:2025/3/21 53 豆豆
生活随笔 收集整理的这篇文章主要介绍了 复习笔记(六)——C++运算符重载(难点) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

运算符重载

运算符重载的概念

运算符重载类似于函数重载。

运算符重载允许把标准运算符(如+、-、*、<等)应用于定制数据类型的对象。

什么情况下需要考虑运算符重载?
需要用运算符操作自定义类的对象时,如对象之间直观自然,可以提高比较大小等,通过重载支持类的运算。

运算符重载:①体现了程序的可读性;②体现了C++的可扩充性

运算符重载的定义

作为类的成员函数或友元函数、作为一般函数(很少用)。

1、成员函数原型的格式:
函数类型 operator 运算符(参数表);
成员函数定义的格式:

函数类型 类名::operator 运算符(参数表) {函数体; }

以成员函数的方式重载运算符
-单目运算符:不带参数,该类对象为唯一操作数
-双目运算符:带一个参数,该类对象为左操作数、参数为右操作数


2、友元函数原型的格式:
friend 函数类型 operator 运算符(参数表);
友元函数定义的格式:

函数类型 operator 运算符(参数表) {函数体; }

以友元函数的方式重载运算符
-单目运算符:带一个参数,该参数为唯一操作数,是自定义类的对象 ++(a)
-双目运算符:带两个参数,第一个参数为左操作数、第二个参数为右操作数,至少有一个参数为自定义类的对象
+(a, b)

实例

#include <iostream> using namespace std;class Complex { public:Complex(double = 0.0, double = 0.0);Complex operator+(const Complex&) const;Complex Add(const Complex&) const;Complex operator-(const Complex&) const;Complex& operator=(const Complex&);void print() const; private:double real; // real partdouble imaginary; // imaginary part }; Complex::Complex(double r, double i) {real = r;imaginary = i; } Complex Complex::operator+(const Complex &operand2) const {Complex sum;sum.real = this->real + operand2.real;sum.imaginary= this->imaginary + operand2.imaginary;return sum; } Complex Complex::Add(const Complex &operand2) const {//功能的实现同上 } Complex Complex::operator-(const Complex &operand2) const {Complex diff;diff.real = real - operand2.real;diff.imaginary=imaginary - operand2.imaginary;return diff; } Complex& Complex::operator=(const Complex &right) {real = right.real;imaginary = right.imaginary;return *this; // enables concatenation } void Complex::print() const {cout<<'('<<real<< "," << imaginary << ')'; } int main() {Complex x, y(4.3, 8.2), z(3.3, 1.1);cout << "x: "; x.print();cout << "\ny: "; y.print();cout << "\nz: "; z.print();x = y + z; //比表达式x=y.Add(z);更简练,更直观cout << "\n\nx = y + z:\n"; x.print();cout << " = "; y.print();cout << " + "; z.print();return 0; }

执行结果:

x: (0,0) y: (4.3,8.2) z: (3.3,1.1)x = y + z: (7.6,9.3) = (4.3,8.2) + (3.3,1.1)

运算符重载的规则

①运算符重载不允许发明新的运算符。

②不能改变运算符操作对象的个数。

③运算符被重载后,其优先级和结合性不会改变。

④不能重载的运算符:

一元运算符重载

操作数是自定义类的对象或对象的引用。

作为成员函数重载没有参数。

作为友元函数重载参数为自定义类的对象或对象的引用(概念介绍)。

实例

(成员函数的方式重载!)

#include <iostream>**自增、自减运算符重载** #include <string.h> using namespace std;class CString { public:CString(const char *s="");CString(const CString& s);~CString();CString& operator = (const CString& s);CString& operator = (const char *s);bool operator !();char *m_str; private:int m_size; }; CString::CString(const CString& s) {m_size=strlen(s.m_str);m_str=new char[m_size+1];strcpy(m_str,s.m_str); } CString::CString(const char *s/* ="" */) {m_size=strlen(s);m_str=new char[m_size+1];strcpy(m_str,s); } bool CString::operator !() {if (strlen(m_str)==0){return true;}elsereturn false; } CString::~CString() {delete []m_str; } int main() {CString s1, s2("some string");if (!s1)//括号中等价于s1.operator!()=>显示调用cout<<"s1 is NULL!"<<endl;else cout<<"s1 is not NULL!"<<endl;if (!s2)cout<<"s2 is NULL!"<<endl;elsecout<<"s2 is not NULL!"<<endl;return 0; }

执行结果:

s1 is NULL! s2 is not NULL!

自增、自减运算符重载

在C++中,单目运算符有++和- -,它们是变量自动增1和自动减1的运算符。在类中可以对这两个单目运算符进行重载。

前置自增和前置自减的重载:
1、成员函数的方式重载,原型为:
函数类型 & operator++();
函数类型 & operator--();
2、友元函数的方式重载,原型为:
函数类型 & operator++(类类型 &);
函数类型 & operator--(类类型 &);

后置自增和后置自减的重载:
1、成员函数的方式重载,原型为:
函数类型 operator++(int);
函数类型 operator--(int);
2、友元函数的方式重载,原型为:
函数类型 operator++(类类型 &,int);
函数类型 operator--(类类型 &,int);

使用前缀运算符的语法格式:++<对象>;
使用后缀运算符的语法格式:<对象>++;

实例

#include <iostream> using namespace std;class CInt { public:CInt(int a=0);void Print();CInt &operator ++();CInt operator ++(int); private:int i; }; CInt::CInt (int a) {i = a; } void CInt::Print() {cout << "i=" << i << endl; } CInt &CInt::operator ++() {++i;return *this; } CInt CInt::operator ++(int) {CInt sum;sum=*this;++i;return sum; } int main(void) {CInt a(5), b(5), c, d;c = a++;d = ++b;cout << "a: ";a.Print();cout << "b: ";b.Print();cout << "c: ";c.Print();cout << "d: ";d.Print();return 0; }

执行结果:

a: i=6 b: i=6 c: i=5 d: i=6

二元运算符重载

1、成员函数的方式重载二元运算符
函数原型:
函数类型 operator 二元运算符(类型 参数);
带有一个参数
左操作数必须为该类的对象或对象的引用

2、二元运算符重载为带有两个参数的非成员函数
函数原型:
函数类型 operator 二元运算符(类型 参数1,类型 参数2);
参数之一必须是类的对象或对象的引用

赋值运算符的重载

1、赋值运算符可直接用在自定义类的对象赋值。

2、如果没有提供重载的赋值运算符函数来复制类的对象。编译器就会提供默认版本的operator=()。

3、赋值运算符的默认版本会简单地进行逐个成员的复制过程,类似于默认的拷贝构造函数。

4、运算符“=”重载时,要检查两个操作数是否为同一个对象。

5、如果对象中包含动态分配的空间,这种赋值方式就不合适了,如:

CString s1("abc"), s2("def"); //具体类见一元运算符重载实例 s1 = s2;

赋值的结果是:对象s1和s2的指针str都指向了同一块数据空间。

6、对象中包含动态分配的空间,赋值运算符需要自己重载,函数实现的算法与拷贝构造函数类似。

实例

#include <iostream> #include <string.h> using namespace std;class CString { public:CString(const char *s="");CString(const CString& s);CString & operator = (const CString & s);CString & operator = (const char *s);char *m_str; private:int m_size; }; CString::CString(const CString& s) {m_size=strlen(s.m_str);m_str=new char[m_size+1];strcpy(m_str,s.m_str); } CString::CString(const char *s/* ="" */) {m_size=strlen(s);m_str=new char[m_size+1];strcpy(m_str,s); } CString& CString::operator =(const CString& str) {if (this!=&str){delete[] m_str;m_size=strlen(str.m_str);m_str=new char[m_size+1];strcpy(m_str,str.m_str);}return *this; } CString& CString::operator =(const char *str) {delete[] m_str;m_size=strlen(str);m_str=new char[m_size+1];strcpy(m_str,str);return *this;//为什么需要返回值? } int main() {CString s1("abc"),s2(s1),s3;s3=s2;cout<<"s1:"<<s1.m_str<<endl; //m_str应该声明成私有,如何输出cout<<"s2:"<<s2.m_str<<endl; //cout<<s2;cout<<"s3:"<<s3.m_str<<endl;s3="tom";cout<<"s3:"<<s3.m_str<<endl;return 0; }

执行结果:

s1:abc s2:abc s3:abc s3:tom

‘+’运算符重载的使用

实例

#include <iostream> #include <string.h> #include <windows.h> using namespace std;class CString { public:CString(const char *s="");CString(const CString& s);CString operator + (const CString &s);CString operator + (const char *s);CString & operator = (const CString & s);CString & operator = (const char *s);char *m_str; private:int m_size; }; CString::CString(const CString& s) {m_size=strlen(s.m_str);m_str=new char[m_size+1];strcpy(m_str,s.m_str); } CString::CString(const char *s/* ="" */) {m_size=strlen(s);m_str=new char[m_size+1];strcpy(m_str,s); } CString CString::operator+(const CString &s) {CString tempStr;char *p=new char[strlen(this->m_str)+strlen(s.m_str)+1];if(p==NULL){exit(1);}strcpy(p,this->m_str);strcat(p,s.m_str);tempStr.m_str=p;return tempStr; } CString CString::operator+(const char *s) {CString tempStr;char *p=new char[strlen(this->m_str)+strlen(s)+1];strcpy(p,this->m_str);strcat(p,s);tempStr.m_str=p;return tempStr; } CString& CString::operator =(const CString& str) {if (this!=&str){delete[] m_str;m_size=strlen(str.m_str);m_str=new char[m_size+1];strcpy(m_str,str.m_str);}return *this; } CString& CString::operator =(const char *str) {delete[] m_str;m_size=strlen(str);m_str=new char[m_size+1];strcpy(m_str,str);return *this; } int main() {CString s1="hello",s2("world"),s3;s3=s1+s2;cout<<"s3 = s1+s2 -- "<<s3.m_str<<endl;s3=s3+"abc"; //s3="abc"+s1; //会出现什么问题?? =>会报错:no match for 'operator+' in '"abc" + s1'cout<<"s3:"<<s3.m_str<<endl;return 0; }

执行结果:

s3 = s1+s2 -- helloworld s3:helloworldabc

重载运算符‘[ ]’

实例

#include <iostream> #include <string.h> #include <windows.h> using namespace std;class CString { public:CString(const char *s="");CString(const CString& s);char operator [](int index);int GetSize();char *m_str; private:int m_size; }; CString::CString(const CString& s) {m_size=strlen(s.m_str);m_str=new char[m_size+1];strcpy(m_str,s.m_str); } CString::CString(const char *s/* ="" */) {m_size=strlen(s);m_str=new char[m_size+1];strcpy(m_str,s); } inline int CString::GetSize() {return m_size; } char CString:: operator [](int index) {if(index<0 || index>=m_size){//下标越界}return m_str[index]; } int main() {CString entry("extravagant");for(int i = 0;i<entry.GetSize();++i){cout<<"entry = "<<entry[i]<<endl;}return 0; }

执行结果:

entry = e entry = x entry = t entry = r entry = a entry = v entry = a entry = g entry = a entry = n entry = t 《新程序员》:云原生和全面数字化实践50位技术专家共同创作,文字、视频、音频交互阅读

总结

以上是生活随笔为你收集整理的复习笔记(六)——C++运算符重载(难点)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。