面向对象程序设计第一次实验课——位运算封装

来源:互联网 发布:sai软件怎么下载 编辑:程序博客网 时间:2024/06/06 14:04

题目的大意是用一个类封装位运算,并通过位运算实现四则运算。我一下子就想起了bitset,但是bitset并不支持四则运算。后来想想也许叫大整数类比较合适吧。

当然还是有很多问题的,有些问题是写完了才发现的,当时发着高烧,一边写一边debug,好不容易赶到deadline前,交过之后也没有改的动力了……

首先是该用友元实现的二元关系的运算符全写在类内了,写之前应该看看书的。其次是没有实现下标运算符的重载,这个要用到设计模式中的代理模式,同样是没来得及写,这里有篇blog里面实现了:
http://blog.csdn.net/fastsort/article/details/8922923

一些其他问题写在了实验报告中。

bit.h

#pragma once#include <string>#include <cstring>#include <cmath>#define BLOCK (len_ / (8 * sizeof(size_t)) + (len_ % (sizeof(size_t) * 8)? 1: 0))#define BLOCKBIT (8 * sizeof(size_t)) using namespace std;template <size_t len_> //len_ is the number of bit(s) class myBitset {    friend ostream& operator<< (ostream &out, const myBitset<len_>& bs)     {        // stored reversely, so output reversely        for (size_t i = 0; i < len_; i ++) {            if (bs.isTrue(len_ - i - 1)) out << "1";            else out << "0";//          printf("%d ",i);        }        return out;    }    public:        myBitset() : block_(BLOCK)         {            num_ = new size_t[block_];              memset(num_, 0, block_ * sizeof(size_t));//          printf("%d %d %d\n", block_, sizeof(size_t), block_ * sizeof(size_t));//          for (int i = 0; i < block_; i ++) num_[i] = 0;//          cout << *this << endl;              }        myBitset(const myBitset& bs);//invert signed number to myBitset, and avoid ambiguous calling for overloaded functions        myBitset(signed int num);        myBitset(unsigned int num);        myBitset(signed long);        myBitset(unsigned long);//      myBitset(signed long long);//      myBitset(unsigned long long);        myBitset(signed __int64 num);        myBitset(unsigned __int64 num);        myBitset(const string& s);        ~myBitset();        myBitset& operator= (const myBitset& bs);        myBitset operator& (const myBitset& bs) const;         myBitset operator| (const myBitset& bs) const;        myBitset operator~ (void) const;        myBitset operator^ (const myBitset& bs) const;    //  BOTH TWO BELOW ARE LOGICAL SHIFT! BE CAREFUL !        myBitset operator<< (size_t shift) const;        myBitset operator>> (size_t shift) const;        myBitset& operator&= (const myBitset& bs);        myBitset& operator|= (const myBitset& bs);        myBitset& operator^= (const myBitset& bs);        myBitset& operator<<= (size_t shift);        myBitset& operator>>= (size_t shift);        myBitset& operator++ (void);        myBitset& operator-- (void);        myBitset operator++ (int dummy);        myBitset operator-- (int dummy);    //  in operator+= we need local variables of myBitset, so argument is not reference        myBitset& operator+= (myBitset bs);        myBitset& operator-= (const myBitset& bs);        myBitset operator+ (const myBitset& bs) const;        myBitset operator- (const myBitset& bs) const;        myBitset operator+ (void) const;        myBitset operator- (void) const;        myBitset operator* (const myBitset& bs) const;        myBitset operator/ (const myBitset& bs) const;//      myBitset operator% (const myBitset& bs) const;        myBitset& operator*= (myBitset bs);        myBitset& operator/= (myBitset bs);        bool operator> (const myBitset& bs) const;        bool operator>= (const myBitset& bs) const;        bool operator< (const myBitset& bs) const;        bool operator<= (const myBitset& bs) const;        bool operator== (const myBitset& bs) const;        bool operator!= (const myBitset& bs) const;        explicit operator bool(void) const;        void flip();// flip all bits        void set(size_t index);        void reset(size_t index);        bool isTrue(size_t index) const;        size_t getBlock(void) { return block_;}        size_t getLen(void) { return len_;}    private:        size_t* num_;   //pointer to where the bits stored        const size_t block_;  //the size of the array   };template <size_t len_> myBitset<len_>::myBitset(const myBitset<len_>& bs) :     block_(bs.block_){    num_ = new size_t[block_];    for (size_t i = 0; i < bs.block_; i ++)         num_[i] = bs.num_[i];}// lower bit is stored in the smaller indextemplate <size_t len_> myBitset<len_>::myBitset(unsigned __int64 num) : myBitset(){    size_t p = 0;//  printf("%llu\n",num);    while (num && p < len_) {        if (num & 1) {            set(p);//          printf("%d\n",p);        }        ++ p;        num >>= 1;    }    // size_t is an unsigned type !!}//template <size_t len_> myBitset<len_>::myBitset(unsigned long long num) : //  myBitset(unsigned __int64(num)) {}template <size_t len_> myBitset<len_>::myBitset(unsigned long num) :     myBitset(static_cast<unsigned __int64>(num)) {}template <size_t len_> myBitset<len_>::myBitset(unsigned int num) :     myBitset(static_cast<unsigned __int64>(num)) {}template <size_t len_> myBitset<len_>::myBitset(signed __int64 num) :     myBitset(static_cast<unsigned __int64>(abs(num))){    if (num < 0) {        flip();        ++ (*this);    }}//template <size_t len_> myBitset<len_>::myBitset(signed long long num) : //  myBitset(signed __int64(num)) {}template <size_t len_> myBitset<len_>::myBitset(signed long num) :     myBitset(static_cast<signed __int64>(num)) {}template <size_t len_> myBitset<len_>::myBitset(signed int num) :     myBitset(static_cast<signed __int64>(num)) {}template <size_t len_> myBitset<len_>::myBitset(const string& s) : myBitset(){    for (size_t i = 0; i < s.size(); i ++) {        if (s[i] != '0') {            set(s.size() - i - 1);        }    }}template <size_t len_> myBitset<len_>::~myBitset(){    delete []num_;}template <size_t len_> inline void myBitset<len_>::set(size_t index){    // 1不加强制类型转换为什么会出现循环左移……     num_[index / BLOCKBIT] |= (size_t(1) << (index % BLOCKBIT));//  printf("%d %d %d\n",index, index / BLOCKBIT, index % BLOCKBIT);    return ;}template <size_t len_> inline void myBitset<len_>::reset(size_t index){    num_[index / BLOCKBIT] &= ~(size_t(1) << (index % BLOCKBIT));    return ;}template <size_t len_> inline bool myBitset<len_>::isTrue(size_t index) const{//  if (num_[index / BLOCKBIT] & (size_t(1) << (index % BLOCKBIT))) printf(" %d %d %d\n",index, index / BLOCKBIT,index %BLOCKBIT);//  printf("%llu\n",1 << (index % BLOCKBIT));    return num_[index / BLOCKBIT] & (size_t(1) << (index % BLOCKBIT));}template <size_t len_> inline void myBitset<len_>::flip(void){    for (size_t i = 0; i < block_; i ++) {        num_[i] = ~num_[i];    }    return ;}template <size_t len_> myBitset<len_>& myBitset<len_>::operator= (const myBitset& bs){    if (this != &bs) {        for (size_t i = 0; i < block_; i ++)            num_[i] = bs.num_[i];    }}template <size_t len_> myBitset<len_> myBitset<len_>::operator&(const myBitset& bs) const{    myBitset<len_> tbs(*this);    tbs &= bs;    return tbs;}template <size_t len_> myBitset<len_> myBitset<len_>::operator|(const myBitset& bs) const{    myBitset<len_> tbs(*this);    tbs |= bs;    return tbs;}template <size_t len_> myBitset<len_> myBitset<len_>::operator~(void) const{    myBitset<len_> tbs(*this);    tbs.flip();    return tbs;}template <size_t len_> myBitset<len_> myBitset<len_>::operator^(const myBitset& bs) const{    myBitset<len_> tbs(*this);    tbs ^= bs;    return tbs;}template <size_t len_> myBitset<len_> myBitset<len_>::operator<<(size_t shift) const{    myBitset<len_> tbs(*this);    tbs <<= shift;    return tbs;}template <size_t len_> myBitset<len_> myBitset<len_>::operator>>(size_t shift) const{    myBitset<len_> tbs(*this);    tbs >>= shift;    return tbs;}template<size_t len_> myBitset<len_>& myBitset<len_>::operator&= (const myBitset& bs){    for (size_t i = 0; i < block_; i ++) {        num_[i] &= bs.num_[i];    }    return *this;}template<size_t len_> myBitset<len_>& myBitset<len_>::operator|= (const myBitset& bs){    for (size_t i = 0; i < block_; i ++) {        num_[i] |= bs.num_[i];    }    return *this;}template<size_t len_> myBitset<len_>& myBitset<len_>::operator^= (const myBitset& bs){    for (size_t i = 0; i < block_; i ++) {        num_[i] ^= bs.num_[i];    }    return *this;}template<size_t len_> myBitset<len_>& myBitset<len_>::operator<<= (size_t shift){    if (shift == 0) return *this;    if (shift >= len_) {        memset(num_, 0, block_ * sizeof(size_t));        return *this;    }    size_t blockShift = shift / BLOCKBIT; // the shift of how many units of array      size_t innerShift = shift % BLOCKBIT; // the shift in the unit of array    for (size_t i = 0; i < block_; i ++) {        size_t opid = block_ - 1 - i;        if (opid < blockShift) {            num_[opid] = 0;        } else {            if (opid - blockShift > 0)                num_[opid]=(num_[opid-blockShift]<<innerShift)|(num_[opid-blockShift-1]>>(BLOCKBIT-innerShift));             else                num_[opid] = num_[opid - blockShift] << innerShift;             }    }    return *this;}template<size_t len_> myBitset<len_>& myBitset<len_>::operator>>= (size_t shift){    //  printf("%llu\n",num_[0]);    if (shift == 0) return *this;    if (shift >= len_) {        memset(num_, 0, block_ * sizeof(size_t));        return *this;    }    size_t blockShift = shift / BLOCKBIT; // the shift of how many units of array      size_t innerShift = shift % BLOCKBIT; // the shift in the unit of array    for (size_t i = 0; i < block_; i ++) {        if (i > block_ - 1 - blockShift) {            num_[i] = 0;        } else {            if (i + blockShift + 1 < block_)                num_[i]=(num_[i+blockShift]>>innerShift)|(num_[i+blockShift+1]<<(BLOCKBIT-innerShift));             else                num_[i] = num_[i + blockShift] >> innerShift;               }    }//  printf("%llu\n",tbs.num_[0]);    return *this;}template <size_t len_>  inline myBitset<len_>& myBitset<len_>::operator++ (void){    (*this) += 1;    return *this;}template <size_t len_>  inline myBitset<len_> myBitset<len_>::operator++ (int dummy){    myBitset<len_> tbs = (*this);    ++ (*this);    return tbs;}template <size_t len_>  inline myBitset<len_>& myBitset<len_>::operator-- (void){    (*this) -= 1;    return *this;}template <size_t len_>  inline myBitset<len_> myBitset<len_>::operator-- (int dummy){    myBitset<len_> tbs = (*this);    -- (*this);    return tbs;}template <size_t len_>  inline myBitset<len_> myBitset<len_>::operator+ (const myBitset& bs) const{    myBitset<len_> tbs(*this);    tbs += bs;    return tbs;}template <size_t len_>  inline myBitset<len_> myBitset<len_>::operator- (const myBitset& bs) const{    myBitset<len_> tbs(*this);    tbs += -bs;    return tbs;}template <size_t len_>  inline myBitset<len_>& myBitset<len_>::operator-= (const myBitset& bs){    *this += -bs;    return *this;}template <size_t len_>  inline myBitset<len_>& myBitset<len_>::operator+= (myBitset bs){    myBitset<len_> tbs;    while ((bs)) {        tbs = (*this) ^ bs;        bs = (*this & bs) << 1;        *this = tbs;    }    return *this;}template <size_t len_>  inline myBitset<len_> myBitset<len_>::operator+ (void) const{    return *this;}template <size_t len_>  inline myBitset<len_> myBitset<len_>::operator- (void) const{    myBitset<len_> tbs(*this);     return ~(tbs) + 1;}template<size_t len_> myBitset<len_>::operator bool(void) const{    for (size_t i = 0; i < len_ ; i ++) {        if (isTrue(i))            return true;    }    return false;}template <size_t len_>  myBitset<len_>& myBitset<len_>::operator*= (myBitset bs){    if (!bs || !*this) {        *this = 0;        return *this;    }    int flag = 0;    myBitset<len_> tbs(*this);    *this = 0;    if (isTrue(len_ - 1)) {        flag = ~flag;        tbs = -tbs;    }    if (bs.isTrue(len_ - 1)) {        flag = ~flag;        bs = -bs;     }    while (bs) {        if (bs & 1)             *this += tbs;        tbs <<= 1;        bs >>= 1;    }    if (flag) {        *this = -(*this);    }    return *this;}template <size_t len_>  myBitset<len_> myBitset<len_>::operator* (const myBitset& bs) const{    myBitset<len_> tbs(*this);    tbs *= bs;    return tbs;}template <size_t len_>  myBitset<len_>& myBitset<len_>::operator/= (myBitset bs){//  cout << *this << " " << bs << endl;    if (bs) {        int flag = 0;        myBitset<len_> tbs(*this);        *this = 0;        if (tbs.isTrue(len_ - 1)) {            flag = ~flag;            tbs = -tbs;        }        if (bs.isTrue(len_ - 1)) {            flag = ~flag;            bs = -bs;         }//      cout << tbs << " " << bs << endl;        size_t highbit = 0;        for (size_t i = len_ - 2; i > 0; i --) {            if (tbs.isTrue(i)) {                highbit = i;                break;            }        }        for (size_t i = 0; i <= highbit; i ++) {            size_t op = highbit - i;            // avoid overflow!!!            if ((tbs >> op) >= bs) {                tbs -= (bs << op);                *this += (myBitset<len_>(1) << op);            }//          cout << op << " " << tbs << " " << bs << " " << *this << endl;        }        if (flag) {            *this = -(*this);        }        return *this;    } else {        cout << "divisor cannot be 0 !" << endl;        return *this;    }}template <size_t len_>  myBitset<len_> myBitset<len_>::operator/ (const myBitset& bs) const{    myBitset<len_> tbs(*this);    tbs /= bs;    return tbs;}template <size_t len_> bool myBitset<len_>::operator>= (const myBitset& bs) const{    return (*this > bs || *this == bs);}template <size_t len_> bool myBitset<len_>::operator> (const myBitset& bs) const{    if (!isTrue(len_ - 1) && isTrue(len_ - 1)) {        return true;    }     if (isTrue(len_ - 1) && !isTrue(len_ - 1)) {        return false;    }    for (size_t i = 0; i < block_; i ++) {        size_t op = block_ - i - 1;        if (num_[op] > bs.num_[op]) {            return true;        }         if (num_[op] < bs.num_[op]) {            return false;        }    }    return false;}template <size_t len_> bool myBitset<len_>::operator== (const myBitset& bs) const{    if (*this ^ bs) {        return false;    } else {        return true;    }}template <size_t len_> inline bool myBitset<len_>::operator< (const myBitset& bs) const{    return !(*this >= bs);}template <size_t len_> inline bool myBitset<len_>::operator<= (const myBitset& bs) const{    return !(*this > bs);}template <size_t len_> inline bool myBitset<len_>::operator!= (const myBitset& bs) const{    return !(*this == bs);}

main.cpp
里面主要是测试

#include <iostream>#include <cmath>#include "bit.h"#include <bitset>using namespace std;int main(int argc, char** argv) {       cout << (-11111 >> 30) << endl;    cout << size_t(-1) << endl;    cout << "test for set, reset and flip" << endl;    myBitset<32> bt;    bt.set(0);    cout << bt << endl;    bt.reset(0);    cout << bt << endl;    bt.set(31);    cout << bt << endl;    bt.flip();    cout << bt << endl;    cout << endl << "test for constructor" << endl;    string s = "100010";    myBitset<32> bt1;    cout << bt1 << endl;    myBitset<33> bt2(s);    cout << bt2 << endl;    myBitset<33> bt31(64);    cout << bt31 << endl;    myBitset<65> bt32(static_cast<unsigned long long>((size_t(1) << 63) + ((size_t(1) << 63) - 1)));    cout << bt32 << endl;    myBitset<33> bt4(bt31);    cout << bt4 << endl;    cout << endl << "test for <<, >> and =" << endl;    myBitset<100> bt5(size_t(pow(2,31))+15);    cout << bt5 << endl;    cout << (bt5 << 4) << endl;    cout << (bt5 >> 4) << endl;    cout << (size_t(1) << 33) << endl;     myBitset<100> bt6("100000011111111111000010101");    cout << bt6 << endl;    bt6 = bt5;    cout << bt6 << endl;    myBitset<129> bt7 = string("10110011101111011111010101");    cout << bt7 << endl;    cout << (bt7 >> 7) << endl;    cout << (bt7 << 7) << endl;    cout << (bt7 << 65) << endl;    cout << (bt7 >> 65) << endl;    cout << endl << "test for &, |, ~ and ^" << endl;    myBitset<70> bt8("1011011101111011111011111101111111011111111011111111101111111111011110");    cout << bt8 << endl;    myBitset<70> bt9(~bt8);    cout << bt9 << endl;    cout << (bt8 | bt9) << endl;    cout << (bt8 & bt9) << endl;    cout << (bt8 ^ bt9) << endl;    cout << (bt8 ^ bt9 ^ bt8) << endl;    cout << endl << "test for &=, |= and ^=" << endl;    cout << bt8 << endl;    bt8 &= bt9;    cout << bt8 << endl;    bt8 |= bt9;    cout << bt8 << endl;    bt8 ^= ~bt9 ^ 1;    cout << bt8 << endl;    cout << endl << "test for <<= and >>=" << endl;    myBitset<70> bt10("1011011101111011111011111101111111011111111011111111101111111111011111");    cout << bt10 << endl;    cout << (bt10 << 65) << endl;    bt10 <<= 65;    cout << bt10 << endl;    bt10 = string("1011011101111011111011111101111111011111111011111111101111111111011111");    cout << (bt10 >> 65) << endl;    bt10 >>= 65;    cout << bt10 << endl;    cout << endl << "test for + and -" << endl;    bt9 = string("1011011101111011111011111101111111011111111011111111101111111111011111");    bt10 = ~bt9;    cout << bt9 << endl;    cout << bt10 << endl;    cout << (-bt9) << endl;    cout << (-bt10) << endl;    cout << (bt9 + bt10) << endl;    cout << (bt9 - (bt10>>3)) << endl;    bt9 = -1;    bt10 = 64;    cout << (bt9 + bt10) << endl;    cout << (bt9 - bt10) << endl;    cout << endl << "test for ++, -- , += and -=" << endl;    bt9 = string("1011011101111011111011111101111111011111111011111111101111111111011111");    bt10 = ~bt9;    cout << (bt9 ++) << endl;    cout << bt9 << endl;    cout << (bt10 --) << endl;    cout << bt10 << endl;    cout << (++ bt9) << endl;    cout << bt9 << endl;    cout << (-- bt10) << endl;    cout << bt10 << endl;    bt10 += 1;    cout << bt10 << endl;    bt10 -= 3;    cout << bt10 << endl;    cout << endl << "test for *, *=, /, /=" << endl;    bt9 = -13;    bt10 = 3;    bt9 *= bt10;    cout << bt9 << endl;    cout << (bt9 * bt10) << endl;    bt9 *= -3;    bt10 *= 100;    cout << bt9 << endl;    cout << bt10 << endl;    cout << endl << "test for /, /=" << endl;    bt9 = 10;    bt10 = 3;    cout << (bt9 >= bt10) << endl;    cout << (bt9 >> 3) << endl;    cout << ((bt9 >> 3) >= bt10) << endl;    cout << (bt9 << 0) << endl;    cout << (myBitset<70>(1) << 0) << endl;    bt9 /= bt10;    cout << bt9 << endl;    bt9 = -10;    bt10 = 3;    cout << (bt9 / bt10) << endl;    cout << (bt10 / bt9) << endl;    return 0;}

附:实验报告

第一次实验报告

一、 题目分析

位运算的封装:
第一次看到这个题目,我想到了stl中的bitset,bitset实现了对bit类型数组的封装,同时支持六种位运算,我的目的就是实现类似于bitset的类模版。
六种位运算& | ~ ^ << >> 支持基础数据类型,但是基础数据类型的大小是固定的,不能支持bit数高于8 * sizeof(size_t)(最大一般是64bit)的要求,而且不能支持任意位数的bit类型数组,这样显然不能满足我们的要求。
因此,我决定使用size_t类型的数组,通过基础类型的位运算实现对每一个size_t内的位的操作,从而实现对抽象的“位类型”的操作。
除了最基础的构造函数、析构函数、拷贝运算符,实现了六种位运算,还实现了布尔类型的类型转换,逻辑运算,和+-*/四则运算和自增自减运算以及流插入操作符重载。

100!的计算:
首先想到的是高精度乘法,通过数组存储大数的每一位,模拟竖式乘法,从而得解。

二、 流程分析(感觉太复杂了画图有些困难,所以通过文字描述)

这里介绍位运算封装的流程,大数阶乘比较简单。
1. 构造函数:
共9个,最基础的是默认构造函数,在其中完成相关变量初始化和内存空间的申请。
之后是拷贝构造函数,myBitset(unsigned __int64 num); myBitset(const string& s); 它们首先使用默认构造函数进行委托构造,之后再实现自己特定的构造。
在之后是以其他各种无符号或有符号整数做参数的构造函数,它们使用myBitset(unsigned __int64 num);进行委托构造,从而完成功能。
2.基础功能的实现
共4个,分别是
void flip();
void set(size_t index);
void reset(size_t index);
bool isTrue(size_t index) const;
flip实现按位取反,set实现对下标是index的置1,reset是实现对下标是index的置0,isTrue判断下标为index的位是否是1,接下来的许多函数都是需要直接或者间接调用这些函数的。
2. 位运算运算符以及=的重载
myBitset& operator= (const myBitset& bs);
myBitset operator& (const myBitset& bs) const;
myBitset operator| (const myBitset& bs) const;
myBitset operator~ (void) const;
myBitset operator^ (const myBitset& bs) const;
myBitset operator<< (size_t shift) const;
myBitset operator>> (size_t shift) const;
myBitset& operator&= (const myBitset& bs);
myBitset& operator|= (const myBitset& bs);
myBitset& operator^= (const myBitset& bs);
myBitset& operator<<= (size_t shift);
myBitset& operator>>= (size_t shift);
首先实现的是&= |= 等函数,之后& |等运算符通过调用&= |= 等实现功能。
3. 四则运算与自增自减
myBitset& operator++ (void);
myBitset& operator– (void);
myBitset operator++ (int dummy);
myBitset operator– (int dummy);
myBitset& operator+= (myBitset bs);
myBitset& operator-= (const myBitset& bs);
myBitset operator+ (const myBitset& bs) const;
myBitset operator- (const myBitset& bs) const;
myBitset operator+ (void) const;
myBitset operator- (void) const;

    myBitset operator* (const myBitset& bs) const;    myBitset operator/ (const myBitset& bs) const;    myBitset& operator*= (myBitset bs);    myBitset& operator/= (myBitset bs);

同样,首先实现的是+= -=等,对应的双目运算符则调用前者,单目-调用~运算符。
前置自增自减调用+= -=,而后置自增自减调用前置自增自减。
4. 逻辑运算符与bool类型转换
bool operator> (const myBitset& bs) const;
bool operator>= (const myBitset& bs) const;
bool operator< (const myBitset& bs) const;
bool operator<= (const myBitset& bs) const;
bool operator== (const myBitset& bs) const;
bool operator!= (const myBitset& bs) const;
explicit operator bool(void) const;
bool类型转换函数调用isTrue函数。
实现的是>和==,其他逻辑运算符直接或间接调用这两个函数。

三、程序难点以及遇到的主要bug

1.构造函数
为了支持四则运算,必须提供参数无符号整型和有符号整型的构造函数,开始我只定义了unsigned __int64和 signed __int64为参数的构造函数,然而这时就会遇到二义调用的问题。
为了避免二义调用,我为常见的整型类型分别定义了构造函数。
2.移位运算
因为存储位的是数组,故实现移位操作时会遇到困难,通过寻找规律可以解决这一问题。
此外还遇到了如下问题。

一开始我并没有对1进行强制类型转换,转换成myBitset类型,按道理,1移位超过int位长时,这样会使1移位后的结果变成0(逻辑移位),但是,这里实际上竟然是循环移位。
而单单对1进行左移位,得到的结果是逻辑移位的结果。
目前还是没有弄明白是为什么。

因为首先实现的是<<=和>>= ,<< >>是通过调用<<= >>= 实现的,移位的时候可能会出现运算结果覆盖未进行运算数据的情况,所以要注意运算的顺序,>>要先从低位开始算,<<要先从高位开始算。

还遇到了移位0时出现的错误,需要特判shift为0时的情况。(除法调用移位操作时发现)
3.bool类型转换
一开始并没有把operator bool 声明为explicit,于是出现了双目运算符调用时的二义调用(左操作数为myBitset对象而右操作数为基础数据类型时),因为myBitset可以隐式的转换为bool类型,c++中bool类型实质上就是int类型。
在查资料之前,我尝试了在声明中加入了explicit关键字,尽管在我的印象中它只能用在构造函数的声明中,但是问题的确解决了,后来查资料发现,在c++11标准中,允许在类型转换运算符前加入explicit的声明,而对bool则更加特殊,在条件表达式中它允许隐式转换而在其他情况中只允许显式使用。
5. 不小心就会发生的间接递归
由于一些运算符要通过调用其他运算符实现,所以在头脑不清晰的情况下极易发生
递归,而且这类错误比较难发现,程序中出现的最长间接递归链甚至可达10个以上的函数。
6. 乘法与除法
在设计乘法的算法时我借鉴了快速幂算法的思想,只不过当第二个乘数为奇数时ans变量做的运算由乘变成了加,只要调用加法就可以实现乘法了。
除法就是乘法的逆运算。
7. size_t类型
size_t类型是一种无符号整数类型,具体类型依赖于环境,但它是非负的,用size_t类型做循环变量时,由于它不可能小于0,于是下面的语句会出现死循环。
For (size_t I = len_ - 1; I >= 0; I ++)
故程序中所有循环尽量写成正序的,需要反向的顺序时,通过循环变量计算出实际运算的下标。

四、 优点与缺点

封装位运算操作符
优点:
a) 实现了任意长度的位类型
b) 满足了所有的要求
c) 尽量使用已定义的方法去定义其他方法
d) 对于多个方法(已实现的或是以后可能实现的)会使用的相同方法,将该方法定义为一个函数
e) 实现了四则运算,自增自减,重载了流插入操作符。
缺点:
a) 最重大的失误:没有将二元运算符用非成员函数实现。(3 + myBitset<10>(1)是非法的)
b) 没有实现[]操作符。(代理模式)
c) 没有用myBitset类实现阶乘(主要是没有转换成整型的方法)
d) 没有定义将myBitset转换为整型的方法(大数进制转换)
e) 部分方法效率不高

0 0