从零开始学习c++之运算符重载与类型转换

本文详细介绍了C++中运算符重载的概念及其使用细节,包括如何选择成员与非成员函数、重载的标准格式及注意事项,并探讨了类型转换运算符的作用及与构造函数的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

运算符重载:

什么是运算符重载:

重载的运算符是特殊名字的函数,名字由operator关键字加上要重载的运算符组成,如operator+,和其他函数一样,重载的运算符也包含返回类型、参数列表和函数体。


运算符重载的使用细节:

(1)当一个运算符函数是成员函数,this绑定到了左侧运算对象。成员运算符函数的(显式)参数数量比运算对象的数量少一个。

(2)除了重载的函数调用运算符operator()之外,其他重载运算符不能含有默认实参。

(3)只能重载现有的运算符,无权发明新的运算符。

(4)运算符的重载不改变运算符优先级。


可以被重载的运算符:

+   -    *    /    %    ^    &    |    ~    !    ,    =    <    >    <=    >=    ++    --    <<    >>    ==    !=    &&    ||    ++    -=    /=    %=    &=    ^=    |=

*=    <<=    >>=    []    ()    ->    ->*    new    new[]    delete    delete[]


不可以重载的运算符:

           ::            .*              .            ?:


调用重载运算符:

data1 + data2;    //普通表达式
operator+(data1,data2);   //等价的函数调用
//这两条语句式等价的,都调用了非成员函数operator+,传入data1和data2作为两个参数
data3 += data4      //基于调用的表达式
data3.operator+=(data2);         //对成员运算符的等价调用
//这两条语句都调用了成员函数 operator+= ,将this绑定到data3的地址,将data4作为实参传入了函数 


重载运算符作为成员函数和非成员函数的选择:

(1)单目运算符应该作为成员函数(不是必须)
(2)= () [] -> ->*必须是成员函数
(3)复合赋值运算符应该作为成员函数
(4)所有其他不是这些二元的运算符应该作为非成员函数


赋值运算符重载标准格式:

T& T::operator=(const T& rhs) {
if (this != &rhs)             //检测自身不等于要赋值的对象
{
//perform assignment
}
return *this;
}


示例代码:

class Integer {
public :
	Integer(int n = 0):i(n){}
	const Integer operator+(const Integer& n) const {
		return Integer(i + n.i);
	}
	int print() { return i; }
private:
	int i;
};
int main()
{
	Integer x(5), y(10), z1,z2,z3;

	z1 = x + y;                  //等同于 z = x.operator+(y)
	z2 = x + 3;                  //Integer类内构造函数被调用Integer(3):i(3){},后z = x.operator+(3)
	//z3 = 3 + y;                  //编译不通过,3为第一个参数所以调用int型+,y不为int型且Integer类内没有方法把y变为int型参数
 
	cout <<"Z1:"<< z1.print() << "\tZ2:" << z2.print() << endl;
   return 0;
}



类型转换:

什么是类型转换:

类型转换运算符是类的一种特殊成员函数,它负责将一个类类型的之转换成其他类型。
标准格式:operator type() const;              //type表示某种类型


类型转换运算符与构造函数:

类型转换和构造函数都能作T => C的类类型转换

(1)T(C)                                 //构造函数
(2)operator T() const;          //C中的类型转换 

class Orange;
class Apple {
public:
	operator Orange() const {}    //类型转换
};

class Orange {
public:
	Orange(Apple) {}       //构造函数     
};

void func(Orange){}     //func函数参数为Orange
int main()
{
    Apple ap;
    func(ap);                  //编译不通过,报错:应用多个用户定义的从Apple到Orange的转换
    return 0;
}
但是当构造函数与类型转换同时存在时,编译器无法知晓应使用哪种函数来进行转换,导致错误。

解决方法:(1)去掉其中一个函数。

                  (2)在构造函数前加explicit关键字,表示此构造函数只能用于构造,不能用于自动类型转换

小结:

应避免过度使用类型转换函数,因其容易形成误导性,所以要防止意外的事情发生。

一般使用一个专门的函数来调用进行类型转换,使程序更加一目了然发生了什么。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值