c++运算符重载

一、概念

如果把运算符看做是一个函数,则运算符也可以像函数一样重载。

C++中预定义的运算符的操作对象只能是基本数据类型。但实际上对于很多用户的自定义类型,也需要类似的运算操作、这时可以在C++中重新定义这些运算符,赋予已有运算符新的功能,使它能够用于特定类型,执行特定的操作。

可以被重载的运算符:

算术运算符:+、-、*、/、%、++、--

位操作运算符:&、|、~、^(位异或)、<<(左移)、>>(右移)

逻辑运算符:!、&&、||

比较运算符:<、>、>=、<=、==、!=

赋值运算符:=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=

其他运算符:[]、()、->、,、new、delete、new[]、delete[]

不被重载的运算符:

成员运算符“.”、指针运算符“*”、三目运算符“? :”、sizeof、作用域“::”

二、友元函数运算符重载

#include <iostream>

#include <string.h>

using namespace std;

int main()

{

string s; // 生成一个空字符串

cout << "判断字符串是否为空:" << s.empty() << endl; // 1

string s1 = "Thursday"; // 隐式调用构造函数,参数const char*

string s2("Thursday"); // 显式调用上面的构造函数

cout << (s1 == s2) << endl; // 1

string s3 = s1; // 隐式调用拷贝构造

string s4(s2); // 显式调用拷贝构造

cout << (s3 == s4) << endl; // 1

s = s4; // 赋值运算符

cout << s << endl; // "Thursday

// 参数1:const char* 原字符串

// 参数2:保留几个字符

string s5("ABCDEFG",2);

cout << s5 << endl; // AB

s = "ABCDEFG";

// 参数1:string 原字符串

// 参数2:不保留前几个字符

string s6(s,2);

cout << s6 << endl; // CDEFG

// 参数1:字符串长度

// 参数2:字符内容

string s7(6,'A');

cout << s7 << endl; // AAAAAA

// 交换

swap(s6,s7);

cout << s6 << " " << s7 << endl; // AAAAAA CDEFG

s = s6+s7; // 拼接

cout << s << endl; // AAAAAACDEFG

// 向后追加

s.append("123");

cout << s << endl; // AAAAAACDEFG123

// 向后追加单字符

s.push_back('%'); // AAAAAACDEFG123%

// 插入

// 参数1:插入的位置

// 参数2:插入的内容

s.insert(1,"222"); // A222AAAAACDEFG123%

// 参数1:删除的起始位置

// 参数2:删除的字符数

s.erase(4,10);

cout << s << endl; // A222123%

// 参数1:替换的起始位置

// 参数2:替换的字符数

// 参数3:替换的内容

s.replace(0,3,"******");

cout << s << endl; // ******2123%

s.clear(); // 清空

cout << s.length() << endl; // 0

char c[20];

s = "1234567890";

// 参数1:拷贝的目标

// 参数2:拷贝的字符数

// 参数3:拷贝的起始位置

s.copy(c,3,1);

cout << c << endl; // 234

// C → C++ 直接赋值即可

// char* → string

char* c1 = "Tom";

char c2[] = "Jerry";

string sc1 = c1;

string sc2 = c2;

cout << sc1 << "&" << sc2 << endl; // Tom&Jerry

// C++ → C

// string → char[]

s = "abcd";

char ch[10];

strcpy(ch,s.c_str()); // c_str()返回值的const char*不稳定

cout << ch << endl;

return 0;

}

 

三、成员函数运算符重载

成员函数运算符重载与友元函数运算符重载的最大区别是:友元函数运算符重载的第一个参数,在成员函数中使用this指针代替,即使用成员函数重载的运算符相比友元函数的参数少一个。

 

#include <iostream>

using namespace std;

/**

* @brief The Integer class 整数类

*/

class Integer

{

private:

int value;

public:

Integer(int value):value(value){}

int get_value() const

{

return value;

}

// 声明成员函数

Integer operator +(const Integer&); // 双目

Integer operator ++(); // 前置

Integer operator ++(int) // 后置

{

return this->value++;

}

};

Integer Integer::operator +(const Integer& i)

{

return this->value + i.value;

}

Integer Integer::operator ++()

{

return ++this->value;

}

int main()

{

Integer i1(1);

Integer i2(2);

Integer i3 = i1 + i2;

cout << i3.get_value() << endl; // 3

cout << (i1++).get_value() << endl; // 1

cout << (++i1).get_value() << endl; // 3

return 0;

}

四、赋值运算符

如果程序员不写赋值运算符重载函数,编译器会为这个类自动添加一个赋值运算符重载函数,且此函数支持链式调用,因此只能使用成员函数运算符重载(不至于友元)。结合之前内容,处理深浅拷贝时应该同时处理赋值运算符。

#include <iostream>

using namespace std;

class Value

{

public:

int value = 0;

// 1. 构造函数

// 2. 拷贝构造

// 3. 析构函数

// 4. 赋值运算符重载

// 编译器自动添加:

Value& operator =(const Value& v)

{

value = v.value;

return *this;

}

};

int main()

{

Value v; // 构造函数

Value v2(v); // 拷贝构造

Value v3 = v2; // 拷贝构造

v.value = 1;

v3 = v; // 赋值运算符

cout << v3.value << endl; // 1

return 0;

}

类型转换运算符与赋值运算符的符号都是=,因此类型转换运算符重载函数的格式比较特殊,以便于与赋值运算符重载进行区分,同样类型转换运算符重载函数也只支持成员函数运算符重载。

#include <iostream>

using namespace std;

class Value

{

private:

int value;

public:

Value(int value):value(value){}

int get_value() const

{

return value;

}

// 类型转换运算符重载函数

operator int()

{

return value;

}

};

int main()

{

// int → Value

Value v = 1; // 隐式构造

// Value → int

int i = v; // 类型转换运算符重载函数

cout << i << endl; // 1

return 0;

}

 

 

五、注意事项

  • 运算符重载限制在C++已有的运算符范围内,不能创建新的运算符。
  • 运算符重载不能改变运算符的优先级、结合性、操作数和语法结构。
  • 运算符重载不能改变基本类型的计算规则,只能更改包含自定义类型的计算规则。
  • 运算符重载实现的功能应该与原运算符相近。
  • 运算符重载函数不支持参数默认值。
  • 通常单目运算符使用成员函数重载,双目运算符使用友元函数重载。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值