C++自增运算符重载——2022年12月~2023年1月cpp学习记录

本文介绍了如何在C++中为自定义类型MyInteger实现自增运算符重载,包括前置++和后置++。首先,通过类定义和构造函数创建MyInteger对象,然后通过重载<<运算符解决输出问题。接着,通过成员函数和全局函数两种方式实现前置++运算符,确保返回类型为MyInteger引用。最后,通过拷贝对象实现后置++运算符,返回自增前的对象副本。文章还探讨了前后置++运算符在链式操作中的区别,并指出后置++无法支持链式操作。

4.5.3 自增(递增)运算符重载

作用:通过重载递增运算符,实现自己的整型数据

项目需求

普通的自增运算符有如下案例:

int a = 0;
cout << ++a << endl;	// 1
cout << a << endl;		// 1

int b = 0;
cout << b++ << endl;	// 0
cout << b << endl;		// 1

项目需求:实现一个自定义的整形类型MyInteger,并且同样实现上述代码的效果:

MyInteger myInt1 = 0;
cout << ++myInt1 << endl;	// 1
cout << myInt1 << endl;		// 1

MyInteger myInt2 = 0;
cout << myInt2++ << endl;	// 0
cout << myInt2 << endl;		// 1

由此可以知道我们如果要实现这个项目,需要有如下步骤:

  1. 自定义一个类型:MyInteger,以仿照int类型
  2. 完成MyInteger类型的<<运算符重载
  3. 完成MyInteger类型的++运算符重载(分为前置++和后置++的实现)

项目实现

定义MyInteger

class MyInteger
{
   
   
public:
	/// <summary>
	/// MyInteger类的无参构造:定义MyInteger类型的变量(对象)且无赋初值的情况下,
	/// (默认)使得其属性value值为0
	/// </summary>
	MyInteger()	
	{
   
   
		value = 0;
	}

	/// <summary>
	/// MyInteger类的有参构造:定义MyInteger类型的变量(对象)且同时赋初值的情况下,
	/// 使用该初值for_value作为其属性value的值
	/// </summary>
	/// <param name="for_value">
	/// :MyInteger类型的变量(对象)定义的同时要赋值给value的初值
	/// </param>
	MyInteger(int for_value)	
	{
   
   
		this->value = for_value;
	}

private:
	int value;
};

以上代码是在我程序中的实际编写情况,为了让我们对代码一目了然,我去掉了一些注释,留下必要的解释,参考代码如下:

class MyInterger
{
   
   
public:
    
    MyInterger()			// 无参构造:为了确保后续我们程序中定义MyInteger类型的变量(对象)且无赋初值的情况下,
    {
   
   						//(默认)使得其属性value为0
		value = 0;
    }
    
	MyInteger(int for_value)// 有参构造:在程序中定义该变量(对象)且同时赋初值的情况下,
	{
   
   						// 使用该初值for_value作为其属性value的值
		this->value = for_value;
	}
    
private:
    
    int value;				// 存储变量(对象)值
};

定义完MyInteger类之后,我们对自定义的MyInteger类进行测试,以检验我们对这个自定义的类能否仿照案例中定义int a = 0int b = 0一样进行变量(对象)的定义:

void test02()
{
   
   
    MyInteger myInt;		// 无赋初值定义MyInteger类型变量myInt
    
	MyInteger myInt1 = 0;	// 赋初值定义MyInteger类型变量myInt1
	MyInteger myInt2 = 0;	// 赋初值定义MyInteger类型变量myInt2
}

编译器编译效果如下:

在这里插入图片描述
编译器没有报错。

说明我们MyInteger类的定义是OK的!但是可能大家这里会有一个问题或者说是一个猜测和思考

小思考:仿照int中的"先定义,后赋值"

既然我们现在这个MyInteger可以仿照int定义的同时不赋初值的变量,也可以仿照int定义的同时有赋初值的变量,那能不能仿照int"先定义,后赋值"的这种情况呢?

这里我做了一下尝试,代码如下:

void test02()
{
   
   
	MyInteger myInt;				// 先定义
	myInt = 10;						// 后赋值
	cout << myInt.value << endl;	// 打印输出,以验证是否真正赋值成功
}

(为了上述代码中的第5行能够访问myInt中的value,我们先把MyInteger中对value的访问权限由private改为public,此处就不作代码展示了,该问题验证完之后我会将权限修改回private

程序运行效果如下:

在这里插入图片描述

程序运行后的确输出了赋值的10…一切看起来都好像挺合理,但要执着追求事物本质的我们怎么可能这么容易就罢休呢?

我们对上面这三行代码的思考的逻辑是这样的:

如果真的是赋值成功,那么这三行代码就应该自始至终都只有一个MyInteger类型的变量myInt存在,也就是说MyInteger的构造函数只调用了一次;

否则,如果MyInteger的构造函数调用了两次及以上就是说明上面三行代码不是一个简单的赋值过程

为了验证我们的这个猜想,我对MyInteger类中的构造函数作了一些该进,改进后的MyInteger类定义如下:

class MyInteger
{
   
   
public:
	MyInteger()	
	{
   
   
		cout << "无参构造调用" << endl;	// 无参构造调用提示
		value = 0;
	}

	MyInteger(int for_value)	
	{
   
   
		cout << "有参构造调用" << endl;	// 有参构造调用提示
		this->value = for_value;
	}

public:
	int value;
};

此时再运行程序,结果如下:

在这里插入图片描述

发现实际上构造函数总共调用了两次,实际上test02()中第二行代码myInt = 10;本质应该是这样的:

myInt = MyInteger(10);

同理第一行代码的本质是:

myInt = MyInteger();

(这里对本质的分析应用的是C++中创建对象时三种方法中的"隐式转换法"的知识)

所以test02()也可以这样写:

void test02()
{
   
   
	MyInteger myInt = MyInteger();	// 先定义
	myInt = MyInteger(
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值