C++运算符重载

简介: 编译器为C++内置类型定义了很多的运算符函数,但是编译器不可能把所有的类型穷举一遍,就算可以,假如有一个我新造了一种类型,我需要对它进行求和、做积、输出等操作,那也是很麻烦,因此C++允许我们对运算符进行重载以支持对各种类型的各种操作。

1.C++运算符重载的作用

 使对象的运算表现得和编译器内置类型一样。如我们想输出一个Complex,希望输出它的实部和虚部,那么我们只需要对<<进行重载即可。为什么不重载cout?因为cout是ostream类型的对象,系统已经给我们定义好了的,我们很难去对它ostream类进行重载。



2.几个例子加深对运算符重载的理解

(1)实现一个简单的Complex类

#include <iostream>usingnamespacestd;
//// 复数类//classCComplex{
public:
// CComplex() CComplex(20)  CComplex(30,30)CComplex(intr=0, inti=0) :mreal(r), mimage(i) { cout<<"CComplex(int r = 0, int i = 0)"<<endl; }
//指导编译器怎么做类对象的加法操作//CComplex operator+(const CComplex& src)//{//  /*CComplex comp;//  comp.mreal = this->mreal + src.mreal;//  comp.mimage = this->mimage + src.mimage;//  return comp;*///  return CComplex(this->mreal + src.mreal, this->mimage + src.mimage);//}voidshow()
    {
cout<<"real:"<<mreal<<"image:"<<mimage<<endl;
    }
CComplexoperator++(int)
    {
returnCComplex(mreal++, mimage++);
    }
CComplex&operator++()
    {
mreal+=1;
mimage+=1;
return*this;
    }
voidoperator+=(constCComplex&src)
    {
mreal+=src.mreal;
mimage+=src.mimage;
    }
private:
intmreal;
intmimage;
friendCComplexoperator+(constCComplex&comp, constCComplex&src);
friendostream&operator<<(ostream&out, CComplexconst&src);
};
CComplexoperator+(constCComplex&comp,constCComplex&src)
    {
/*CComplex comp;comp.mreal = this->mreal + src.mreal;comp.mimage = this->mimage + src.mimage;return comp;*/returnCComplex(comp.mreal+src.mreal, comp.mimage+src.mimage);
    }
ostream&operator<<(ostream&out, CComplexconst&src)
    {
out<<"mreal:"<<src.mreal<<"mimage:"<<src.mimage<<endl;
returnout;
    }
intmain(void)
{
CComplexcomp1(10, 10);
CComplexcomp2(20, 20);
// comp1.operator+(com2)   加法运算符的重载函数//CComplexcomp3=comp1+comp2;
comp3.show();
CComplexcomp4=comp1+10;//comp1.operator+(10);comp4.show();
//编译器做对象运算的时候,会调用对象的运算符重载函数(优先调用成员方法);如果没有成员方法,就在全局作用域找合适的运算符重载函数   ::operator+(30,comp1)CComplexcomp5=10+comp1;
comp5.show();
//CComplex operator(int){}comp5=comp1++;//++ --单目运算符  operator++()前置++     operator++(int)后置++comp1.show();
comp5.show();
//CComplex operator(){}comp5=++comp1;
comp1.show();
comp5.show();
/*CComplex* c = &(comp1++);*//*comp1++.operator=(comp5);*//*comp1.show();*/comp1+=comp2;
comp1.show();
cout<<comp1;
return0;
}


(2)实现一个简单的string类

#include <iostream>usingnamespacestd;
#include <string>//自己实现一个字符串classMyString{
public:
MyString(constchar*p=nullptr)
    {
if (p!=nullptr)
        {
_pstr=newchar[strlen(p) +1];
strcpy(_pstr, p);
        }
else        {
_pstr=newchar[1];
_pstr[0] ='\0';
        }
    }
MyString(constMyString&str)
    {
_pstr=newchar[strlen(str._pstr) +1];
strcpy(_pstr, str._pstr);
    }
~MyString()
    {
delete[]_pstr;
_pstr=nullptr;
    }
MyString&operator+(constMyString&str)
    {
if (this==&str)//排除自赋值        {
return*this;
        }
delete[]_pstr;
_pstr=newchar[strlen(str._pstr) +1];
strcpy(_pstr, str._pstr);
return*this;
    }
booloperator>(constMyString&str) const    {
returnstrcmp(_pstr, str._pstr) >0;
    }
booloperator<(constMyString&str) const    {
returnstrcmp(_pstr, str._pstr) <0;
    }
booloperator=(constMyString&str) const    {
returnstrcmp(_pstr, str._pstr) ==0;
    }
intlength()const    {
returnstrlen(_pstr);
    }
char&operator[](intindex)
    {
return_pstr[index];
    }
constchar&operator[] (intindex)const    {
return_pstr[index];//不能作为左值    }
constchar*c_str()const    {
return_pstr;
    }
private:
char*_pstr;
friendostream&operator<<(ostream&out, constMyString&str);
friendMyStringoperator+(constMyString&str1, constMyString&str2);
};
MyStringoperator+(constMyString&str1, constMyString&str2)
{
char*ptmp=newchar[strlen(str1._pstr) +strlen(str2._pstr) +1];
strcpy(ptmp, str1._pstr);
strcat(ptmp, str2._pstr);
MyStringtmp(ptmp);
delete[]ptmp;
returntmp;
/*return MyString(ptmp);*/}
ostream&operator<<(ostream&out, constMyString&str)
{
out<<str._pstr;
returnout;
}
intmain(void)
{
MyStringstr1;
MyStringstr2="aaa";
MyStringstr3="bbb";
MyStringstr4=str2+str3;
MyStringstr5=str2+"ccc";
MyStringstr6="ddd"+str2;
cout<<"str6"<<str6<<endl;
if (str5>str6)
    {
cout<<str5<<">"<<str6<<endl;
    }
else    {
cout<<str6<<"<"<<str6<<endl;
    }
intlen=str6.length();
for (inti=0; i<len; ++i)
    {
cout<<str6[i] <<" ";
    }
cout<<endl;
charbuf[1024] = { 0 };
strcpy(buf, str6.c_str());
return0;
}
相关文章
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
94 5
|
6月前
|
编译器 C++
C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)
C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)
54 1
|
7月前
|
程序员 编译器 C++
C++中的运算符重载(Operator Overloading)
C++中的运算符重载(Operator Overloading)
62 1
|
3月前
|
C++
C++(十五) 运算符重载
C++中的运算符重载允许对已有运算符的功能进行重新定义,从而扩展语言功能、简化代码并提升效率。重载遵循特定语法,如 `friend 类名 operator 运算符(参数)`。重载时需注意不可新增或改变运算符数量、语义、优先级、结合性和返回类型。常见示例包括双目运算符 `+=` 和单目运算符 `-` 及 `++`。输入输出流运算符 `&lt;&lt;` 和 `&gt;&gt;` 也可重载。部分运算符只能作为成员函数重载。
|
6月前
|
存储 编译器 C++
【C++】:拷贝构造函数和赋值运算符重载
【C++】:拷贝构造函数和赋值运算符重载
34 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==`。赋值运算符应返回引用并检查自我赋值。当未显式重载时,编译器提供默认实现,但这可能不足以处理资源管理。拷贝构造和赋值运算符在对象复制中有不同用途,需根据类需求定制实现。正确实现它们对避免数据错误和内存问题至关重要。接下来将探讨更多操作符重载和默认成员函数。