栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

C++学习日记——运算符重载

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++学习日记——运算符重载

1. 基本用法

对已有的运算符重新进行定义,赋予其新的意义,适应不同的数据类型。
运算符重载分为成员函数实现,全局函数实现。
运算符重载使用的函数名为"operator" + “运算符”,全局函数和成员函数区别在于调用和参数,以下对几个典型的运算符进行重载举例。

2. 重载分类
  1. 运算符重载:+、-、*、/;
  2. 左移运算符:<<;
  3. 递增(减)运算符:++、–;
  4. 赋值运算符:=;
  5. 关系运算符:>、<、==、>=、<=、!=;
  6. 函数调用运算符:();
3. 加号的重载(使用成员函数)

使用背景:对于两个自定义的类Card,两个卡片合成时,等级相加后减去和的1/10,不足1按照1来算。

class Card
{
	friend void Levelup();	// 嗯哼~
public:
	Card(int level, string name) :Level(level), Name(name)	// 类的初始化
	{
		cout << this->Name << "初始化成功!" << endl;
	}
	
	Card operator+(Card &c2) {		// 成员函数运算符重载
		Card temp(0, "new_card");

		temp.Level = (int)((this->Level + c2.Level) * 9 / 10);
		return temp;
	}
private:
	int Level;
	string Name;
};

void Levelup()
{
	Card c1(5, "Card_1"), c2(6, "Card_2");

	Card c3 = c1 + c2;

	cout << "第一张卡等级为:" << c1.Level << ",名称为:" << c1.Name << endl;
	cout << "第二张卡等级为:" << c2.Level << ",名称为:" << c2.Name << endl;
	cout << "新卡等级为:" << c3.Level << ",名称为:" << c3.Name << endl;
}

运行截图:

4. 乘号的运算符重载(使用全局函数)

使用背景:对于一个字符串,乘以几就复制几次并输出。

#include
#include

using namespace std;

string operator*(string &str, int num)
{
	string *temp;
	temp = new string[sizeof(str) * num - (num - 1)];

	for (int i = 0; i < num; i++)
	{
		*temp += str;
	}
	return *temp;
}

int main()
{
	string str1 = "abc";

	string str2 = str1 * 3;		// 调用本质为string str2 = operator*(str1, 3);

	cout << "原本字符串:" << str1 << endl;
	cout << "复制之后字符串:" << str2 << endl;

	system("pause");
	return 0;
}

运行截图:

5. 递增运算符重载
class MyInt
{
public:
    MyInt(int a):myint(a){  }
    // 重载前置运算符
    MyInt& operator++()		// 返回值为引用
    {
        myint++;
        return *this;
    }
    // 重载后置运算符
    MyInt operator++(int)   // 返回值为值,并且使用int占位参数
    {
        // 先记录
        MyInt temp = *this;
        //后自增
        myint++;
        // 最后返回记录值
        return temp;
    }	// 这种写法,也就决定了后置递增运算符无法进行链式编程
    // 通过两个运算符重载,可以更加清楚的了解到,前置运算符效率更高

private:
    int myint;
}
6. 赋值运算符重载

对类初始化时,编译器自动重载赋值操作,用来两个类之间的赋值。但是对于编译器提供的赋值运算符重载是,浅拷贝层次的。为了满足需要,一般会在成员变量有指针的情况下考虑我们自行对赋值运算符进行重载。这里不做仔细讨论。

值得注意的是:

  • 在进行深拷贝时,注意改变的指针是否已经指向堆区的一段空间。如果有,记得先释放,后申请。(养成好习惯!);
  • 想要赋值运算符可以实现链式编程,返回值要写为自身的引用;
7. 关系运算符重载

目的是为了满足用户自定义的类之间的比较运算。

8. 函数调用运算符重载

这个运算符重载之后的使用方式非常像函数的调用,因此成为仿函数;
举例:

#include 
#include 

using namespace std;

class Print
{
public:
    void operator()(string str)
    {
        cout << str << endl;
    }
};

void print_func(string str)
{
    cout << str << endl;
}

int main()
{
    Print print_class;

    print_class("HelloWorld!");
    print_func("HelloWorld!");
    
    system("pause");
    return 0;
}

仿函数非常灵活,没有固定的写法。

9. 运算符重载注意事项
  1. 运算符重载也可以发生函数重载;
  2. 一般不会利用成员函数重载左移运算符<<,因为无法实现对象p在右侧;在重载左移运算符时,使用
osteam& operator<<(ostream &cout, 类名 p)
{ 
	// ...
	return cout;
}
  1. 重载左移运算符配合友元可以实现输出自定义数据类型;
  2. 重载前置运算符时,返回值类型设置为引用可以进行链式编程;重载后置运算符时,使用占位参数来和前置运算符作以区分,返回值类型应当设置为值;
10. 放松时刻



提一嘴,这点痛苦,终于过去了。
在这儿,基本没有有意思的东西来玩,就很枯燥。不过好在都过去啦!继续加油!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/992637.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号