c++,ビット演算の計算式
(参考書:明解c++中級編)
1添え字演算子[]のreturn BitOfByteRef(vec[i / CHAR_BITS], (i & (CHAR_BITS - 1)));
の計算式がどのようになっているか解説してほしいです。
2また、添え字演算子[]の範囲エラーのthrow IdxRngErr(this, i);
でなぜthisも返す必要があるのかを知りたいです。//ここです
3また、真偽を設定という部分のコメントアウトしてる部分の式がないをしているかを教えていただけますでしょうか。
BitOfByteRef& operator=(bool b) { // 真偽を設定
if (b)
vec |= 1 << idx;//
else
vec &= ~(1 << idx);//
return *this;
}
template<> class Array<bool> {
typedef unsigned char BYTE;
static const int CHAR_BITS = std::numeric_limits<unsigned char>::digits;
int nelem; // bool型配列の要素数
int velem; // bool型配列を格納するためのBYTE型配列の要素数
BYTE* vec; // BYTE型先頭要素へのポインタ
// bool型sz個の要素の格納に必要なBYTE型配列の要素数
static int size_of(int sz) { return (sz + CHAR_BITS - 1) / CHAR_BITS; }
public:
void f() {
std:: cout << CHAR_BIT << std::endl;
}
//=== ビットベクトル(バイト)中の1ビットへの参照を表すためのクラス ===//
class BitOfByteRef {
unsigned char& vec; // 参照先BYTE
int idx; // 参照先BYTE中のビット番号
public:
BitOfByteRef(BYTE& r, int i) : vec(r), idx(i) { } // コンストラクタ
//ここです↓
operator bool() const { return (vec >> idx) & 1; } // 真偽を取得
BitOfByteRef& operator=(bool b) { // 真偽を設定
if (b)
vec |= 1 << idx;
else
vec &= ~(1 << idx);
return *this;
}
};
//----- 添字範囲エラー -----//
class IdxRngErr {
const Array* ident;
int index;
public:
IdxRngErr(const Array* p, int i) : ident(p), index(i) { }
int Index() const { return index; }
};
//--- 明示的コンストラクタ ---//
explicit Array(int sz, bool v = bool()) : nelem(sz), velem(size_of(sz)) {
vec = new BYTE[velem];
for (int i = 0; i < velem; i++) // 全要素を初期化
vec[i] = v;
}
//--- コピーコンストラクタ ---//
Array(const Array& x) {
if (&x == this) { // 初期化子が自分自身であれば…
nelem = 0;
vec = NULL;
}
else {
delete[] vec;
nelem = x.nelem; // 要素数をxと同じにする
velem = x.velem; // 要素数をxと同じにする
vec = new BYTE[velem]; // 配列本体を確保
for (int i = 0; i < velem; i++) // 全要素をコピー
vec[i] = x.vec[i];
}
}
//--- デストラクタ ---//
~Array() { std::cout << "です\n"; delete[] vec; }
//--- 要素数を返す ---//
int size() const { return nelem; }
//--- 代入演算子= ---//
Array& operator=(const Array& x) {
if (&x != this) { // 代入元が自分自身でなければ…
if (velem != x.velem) { // 代入前後の要素数が異なれば…
delete[] vec; // もともと確保していた領域を解放
velem = x.velem; // 新しい要素数
vec = new BYTE[velem]; // 新たに領域を確保
}
nelem = x.nelem; // 新しい要素数
for (int i = 0; i < velem; i++) // 全要素をコピー
vec[i] = x.vec[i];
}
return *this;
}
//--- 添字演算子[] ---//
BitOfByteRef operator[](int i) {
if (i < 0 || i >= nelem)
throw IdxRngErr(this, i); // 添字範囲エラー送出
return BitOfByteRef(vec[i / CHAR_BITS], (i & (CHAR_BITS - 1)) );
}
//--- 添字演算子[] ---//
bool operator[](int i) const {
if (i < 0 || i >= nelem)
throw IdxRngErr(this, i); // 添字範囲エラー送出
return (vec[i / CHAR_BITS] >> (i & (CHAR_BITS - 1)) & 1U) == 1;//
}
};
#endif