您的位置:首页 > 其它

bitset类学习(补充)

2014-04-07 18:09 417 查看
// Bitset.cpp : 定义控制台应用程序的入口点。
//VS 2005 测试

#include "stdafx.h"
#include <iostream>
#include <bitset>
#include <typeinfo>

using namespace std;

namespace X_BitSet{

	template<size_t N>
	class MyBitset{
	public:
		//reference 类
		class reference{
			friend reference;
			reference();
			/*
				这里把 reference 的构造函数声明为私有,那么在外部就不能定义reference的对象
				为什么要加入reference类?
				bitset的取值也是一种结构,reference类就提供对这个结构的操作。
			*/
		public:
			~reference();
			reference& operator=(bool x);	//用于b[i]=x
			reference& operator=(reference&);//用于b[i] = b[j]
			bool operator ~()const;					//返回~b[i];
			operator bool()const;					//用于x = b[i]			?????
			reference& flip();							//b[i].flip();
		};

		//构造函数
		MyBitset();		//N个二进制位0
		MyBitset(unsigned long val);	//
		
		/*
			借助下面的构造函数思考下模板的参数演绎问题,bt = bitset<4>(strBinary);		//ok--------bt[4](0,1,1,1)	调用的就是下面的
			构造函数。
			str => template<class Ch,class Tr, class A>
			str在没有模板参数的情况下可以演绎出 template<class Ch,class Tr, class A>,这与:
				模板参数演绎过程中不允许进行自动类型转换
			不冲突。所以自动演绎应该是没问题的。
																												(个人理解,仅供参考)
		*/
		template<class Ch, class Tr, class A>
		explicit MyBitset(const basic_string<Ch,Tr,A>& str, 
			typename basic_string<Ch,Tr,A>::size_type pos = 0,
			typename basic_string<Ch,Tr,A>::size_type n = basic_string<Ch,Tr,A>::npos);

		//bitset操作
		reference operator[](size_t pos);						//b[i]
		MyBitset& operator&=(const MyBitset& s);		//与
		MyBitset& operator|=(const MyBitset& s);		//或
		MyBitset& operator^=(const MyBitset& s);		//异或

		MyBitset& operator<<(size_t n);				//逻辑左移(填充0)
		MyBitset& operator>>(size_t n);				//逻辑右移(填充0)

		MyBitset& set();										//将所有位置为1
		MyBitset& set(size_t pos, int val = 1);		//b[pos] = val;

		MyBitset& reset();									//所有位设置为0
		MyBitset& reset(size_t pos);					//b[pos] = 0			注意:这里跟set不同

		MyBitset& flip();										//改变没个位的值
		MyBitset& flip(size_t pos);						//改变 b[pos] 的值

		MyBitset operator~()const{return MyBitset<N>::(*this).flip();}		//做出补集		注意:这里返回的不是bitset的引用
		MyBitset operator<<(size_t n)const{return (*this)<<n;}
		MyBitset operator>>(size_t n)const{return (*this)>>n;}

		//其他操作
		unsigned long to_long()const;

		template<class Ch,class Tr,class A>
		basic_string<Ch,Tr,A> to_string()const;

		size_t size()const;					//位数
		size_t count()const;				//值为1的二进制位数		

		bool operator==(MyBitset<N>& s)const;
		bool operator!=(MyBitset<N>& s)const;

		bool test(size_t pos)const;		//如果 b[pos] 为1则为true
		bool any()const;						//如果任何位为1则为true
		bool none()const;					//如果没有位为1则为true

	};
}

int _tmain(int argc, _TCHAR* argv[])
{
	string strBinary;
	strBinary.assign("11101011");	//[0] = 1 ; [1] = 1 ; [2] = 1 ; [3] = 0.....
	bitset<4> bt,bt2;

	try{
		//字符串构造
		bt = bitset<4>(strBinary);		//ok--------bt[4](0,1,1,1)	
		bt = bitset<4>(strBinary,1,2);	//ok--------bt[4](1,1,0,0)	
		bt = bitset<4>(strBinary,1,1);	//ok--------bt[4](1,0,0,0)
		bt = bitset<4>(strBinary,1,0);	//ok--------bt[4](0,0,0,0)
		//bt = bitset<4>(strBinary,10,13);	//error throw out_of_range::invalid bitset<N> position
		strBinary.assign("abc123");
		//bt = bitset<4>(strBinary);		//error throw invalid_argument::invalid bitset<N> char

		//unsiged long 构造
		bt = 0x0e;				//ok--------bt[4](0,1,1,1)
		bt = 0x01;				//ok--------bt[4](1,0,0,0)

		//bitset操作
		bt.flip();						//ok--------bt[4](0,1,1,1)
		//bt.flip(4);					//error throw out_of_range::invalid bitset<N> position		

		bt.reset(3);					//ok--------bt[4](0,1,1,0)
		bt.set(2);					//ok--------bt[4](0,1,1,0)

		bt2 = bt;					//ok--------bt2[4](0,1,1,0)
		bt2 = bt << 1;			//ok--------bt2[4](0,0,1,1)

		/*
			下面的两个操作用到的是reference类的成员函数
		*/
		bt2.at(0).flip();			//ok--------bt2[4](1,0,1,1)
		bt2.at(3) = ~bt2[3];		//ok--------bt2[4](1,0,1,0)

		//其他操作		bt[4](0,1,1,0)
		size_t bSize = bt.size();			// = 4
		size_t bCount = bt.count();		// = 2
		 
		bool bAny = bt.any();				// = true
		bool bNone = bt.none();			// = false

		unsigned long to_long = bt.to_ulong();	// = 6
		string strToString = bt.to_string();			// = "0110"
		bt.set(3);											//ok--------bt[4](0,1,1,1)
		strToString = bt.to_string();					// = "1110"
		
		//
		size_t s = sizeof bt;							// = 4
		bitset<100> bt100;
		bitset<1> bt1;
		s = sizeof bt100;								//16
		s = sizeof bt1;									//4
		
		cout << typeid(bt).name() << endl;		//class std::bitset<4>
		cout << typeid(bt.at(0)).name() << endl;	//class std::bitset<4>::reference
	}
	catch(out_of_range& o)
	{
		cout << o.what() << endl;
	}
	catch(invalid_argument& a)
	{
		cout << a.what() << endl;
	}
	catch(overflow_error& ov)
	{
		cout << ov.what() << endl;
	}
	system("pause");
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: