2015-09-19 44 views
0

免責聲明 - 這是一所學校的分配,但問題依然很有意思,我希望!自定義實現與位表示一個布爾值向量的 - 如何實現運營商[]

我已經實現了一個名爲Vector<bool>的自定義類,它將bool條目存儲爲數組數組中的位。

一切都消失了,除了罰款執行本:

bool& operator[](std::size_t index) { 
    validate_bounds(index); 
    ??? 
} 

const實現是相當簡單的,只是讀出值。然而,在這裏我無法真正理解要做什麼,而且該課程是關於C++的專業課程,所以我猜測我應該做一些類型設計或其他事情。數據由unsigned int類型的數組表示,並且應該是動態的(例如,應該實施push_back(bool value))。

+9

典型方法涉及返回代理類的實例 - 其保持參考回容器類,以及它所代表的比特的索引。然後這個類將提供相應地讀取和寫入該位的'operator bool()'和'operator =(bool)'。 –

+6

這幾乎是每個人都討厭'std :: vector '的原因。它的接口要求與其他所有內容不一致,包括所有其他類型的向量。 – chris

+1

我不討厭它。 ;)雖然它不應該是'std :: vector',IMO的專門化,就像'std :: bit_vector'。 – cubuspl42

回答

0

基本上實現operator []是一樣的落實常量操作符[]正如您所料,這只是一個是可寫的(左值),另一種是隻讀(右值)。

我認爲您已經理解了這個問題:您可以使用按位運算將unsigned int轉換爲bool,還可以說「如果第n個bool在X中進行了修改,則使用X進行按位運算它完成了!「。但是這個操作符意味着:我想要一個bool的左值,所以我可以隨時修改它,並且對相關的整數有影響。這意味着你需要一個bool引用,或者在你的情況下引用一個位,所以你可以即時修改這個位。不幸的是,你不能引用一個位,你可以做的最小的是一個完整的字節(與char),所以你將不得不與你至少有7個其他布爾值。這不是你想要的。

話雖這麼說,我明白,這可能是你的任務,但將布爾變量分成多個unsigned int類型更像是沒用的C類優化我。有一個單一的bool數組(C風格),並且手動執行內存處理會更好,因爲這幾乎就是你在做什麼。再加上這種方法,你實際上可以引用一個布爾值(並且能夠修改它)而不會觸及其他布爾值。你必須使用一個unsigned int數組來完成這個任務嗎?

+0

是的,我必須使用一個'unsigned int'數組。此外 - 我認爲我可以使用代碼類在問題的評論中提到的那裏,我返回一個代理類,其中包含一個'unsigned int'的引用以及要修改哪個位的索引 - 索引可以存儲在一個字節。如果沒有人發佈答案,我會在我完成後發佈我的答案。 –

+0

現在查看我的答案。 –

1

我解決了這個實現的代理類:

class BoolVectorProxy { 
public: 
explicit BoolVectorProxy(unsigned int& reference, unsigned char index) { 
    this->reference = &reference; 
    this->index = index; 
} 

void operator=(const bool v) { 
    if (v) *reference |= 1 << index; 
    else *reference &= ~(1 << index); 
} 

operator bool() const { 
    return (*reference >> index) & 1; 
} 

private: 
    unsigned int* reference; 
    unsigned char index; 
}; 

和主類中:

BoolVectorProxy operator[](std::size_t index) { 
    validate_bound(index); 
    return BoolVectorProxy(array[index/BLOCK_CAPACITY], index % BLOCK_CAPACITY); 
} 

我還使用捕捉作爲測試庫,代碼通過測試:

TEST_CASE("access and assignment with brackets", "[Vector]") { 
    Vector<bool> a(10); 
    a[0] = true; 
    a[0] = false; 
    REQUIRE(!a[0]); 

    a[1] = true; 
    REQUIRE(a[1]); 

    const Vector<bool> &b = a; 
    REQUIRE(!b[0]); 
    REQUIRE(b[1]); 

    a[0] = true; 
    REQUIRE(a[0]); 
    REQUIRE(b[0]); 
    REQUIRE(b.size() == 10); 

    REQUIRE_THROWS(a[-1]); 
    REQUIRE_THROWS(a[10]); 
    REQUIRE_THROWS(b[-1]); 
    REQUIRE_THROWS(b[10]); 
} 

如果有人認爲,可以由任何問題或改進,請發表評論,謝謝!