重载下标运算符[]

9 篇文章 0 订阅

看了bitset的源码,发现要重载下标运算符[]内容还挺多的,作右值时相对简单,只用来测试。作左值时就比较麻烦,因为要修改它的值。

 

1、作右值

举个例子:

const bitset<10> b;
bool tag;
tag = b.test(2);
tag = b[2];

上面第三句和第四句效果一样,都是测试b的下标为2的位是否为1。
当bitset为const时,operator[]执行的是:

bool operator[](size_t _Pos) const
{	// subscript nonmutable sequence
	return (test(_Pos));
}

可以看到,内部还是调用了test。

 

2、作左值

举个例子:

bitset<10> b;
b.set(2);
b[2] = 1;  // 或b.operator[](2) = 1; // 或(b.operator[](2)).operator=(1);

上面的第二句和第三句效果一样,都是将b的下标为2的位设置为1,其实执行第三句时内部还是要调用set()的。

下面详细介绍:

#include <iostream>
#include <bitset>
using namespace std;

int main(int argc, char **argv)
{
	bitset<10> b;

	// 第1步
	bitset<10>::reference r = b.operator[](2);  
	// 函数名是operator[],实参是2,返回reference对象

	// 第2步
	r.operator=(1);
	// 这里r._Pbitset与&b相等(原理就是r用_Pbitset记住了b的地址),故改变了*_Pbitset也就改变了b
	// r无任何改变

	// 最后结果
	// r._Pbitset:[bitset]	[10](0,0,1,0,0,0,0,0,0,0)	类型:std::bitset<10> *
	// b:					[10](0,0,1,0,0,0,0,0,0,0)	类型:std::bitset<10>
	// 两者是一致的
	return 0;
}

关于bitset类的定义,下面是个简化版:

// bitset类的简化版
// 为了与库bitset区别,这里首字母大写
class Bitset
{
public:
	class Reference
	{
		friend class Bitset; // 为了Reference外Bitset内的operator[]能访问Reference构造函数(private)

	public:
		Reference& operator=(bool _Val)		// 第2步,还是要调用set
		{
			_PBitset->set(_Mypos, _Val);	// r没变,但(*_PBitset)即b改变了
			return (*this);
		}

	private:
		Bitset *_PBitset;	//  Key
		size_t _Mypos;
		Reference(Bitset& _Bitset, size_t _Pos) : _PBitset(&_Bitset), _Mypos(_Pos)
		{
			// 构造函数
		}
	};

	Reference operator[](size_t _Pos)  // 第1步
	{
		return (Reference(*this, _Pos));
		// 这个地方用法很怪!直接调用构造函数,创建一个无名的临时对象
	}

	Bitset& set(size_t _Pos, bool _Val = true)
	{
		// 略
	}
};

 下面摘录自《C++ Primer》(李师贤译)P94:

下标操作返回左值,因此可将下标操作作为赋值操作的左操作数。对下标操作的结果赋值是赋一个新值到相应的元素。

但我认为这是有前提的!如第一种情况,读const bitset时调用的operator[]返回的就是bool类型,而非reference类型。

关于bitset的源码,可以在VC\include\bitset中找到。

最后一个问题:

bitset<10> b;
bool tag;
tag = b[2];

这个测试又跟第一种不同了,其实这种情况比const那种测试常见地多,下次再介绍了。

 

 

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值