Bit array implementation I have made a bit array implementation that can be seen below:

unsigned int uint_size();

class Bitarray1D {
private:
    unsigned int * array_;
    int elements_;
    int bits_;

public:
    Bitarray1D(int bits);

    ~Bitarray1D();

    void size(int&amp; bits) const;

    unsigned int count() const;

    void setAll(int value);

    void set(int index, int value);

    int test(int index) const;

    unsigned int operator [](int index) const;

    void flip(int index);

    std::string to_string() const;

private:
    void init();

};


and some of the functions:

void Bitarray1D::init(){
        if (bits_ == 0) throw std::invalid_argument("Can't initialize zero size array");

        int number_of_elements = bits_;
        std::cout &lt;&lt; "unsigned int size: " &lt;&lt; uint_size() &lt;&lt; " bytes" &lt;&lt; std::endl;

        elements_ = std::ceil((bits_*1.0)/(uint_size()*1.0));
        array_ = new unsigned int[elements_];
}

int Bitarray1D::test(int index) const {
        if (index &lt; 0 || index &gt;= bits_) throw std::out_of_range("Index out of range");

        int element = index / uint_size();
        int bit = index % uint_size();

        unsigned int temp_element = array_[element];
        temp_element = temp_element &gt;&gt; bit;

        unsigned int mul = 1;
        temp_element = temp_element &amp; mul;
        return temp_element;
}

unsigned int Bitarray1D::operator [] (int index) const {
        if (index &lt; 0 || index &gt;= bits_) throw std::out_of_range("Index out of range");

        return test(index);
}


uint_size() is a function that returns the size of an unsigned int in bytes.

While this works well, i want to implement the assignment in array-like style as well, i.e.: bitarray[i] = 1;

In the current implementation this is not possible. In order to do so, I figured that [] operator in Bitarray should return a "Bit object" with the appropriate operators like below:

class Bit{
  private:
        unsigned int&amp; element_;
        unsigned int index_;

    int getValue() const{
        // get value of bit
    }
public:
    Bit(unsigned int&amp; element, unsigned int index): element_(element), index_(index){}

    Bit&amp; operator [] (int value){
        return *this;
    }

    Bit&amp; operator = (int value){
          //assign value to the bit
    }

    friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const Bit&amp; bit){
        os &lt;&lt; bit.getValue();
        return os;
    }
};


This implementation works, but has two major problems:


Memory leak. In order for the [] operator in Bitarray to return a reference to a Bit object I have to return the following:

Bit&amp; Bitarray1D::operator [] (int index) const {
     return *(new Bit(..., ... ));
}

I could change the array_ of the bitarray to hold an array of class Bit, but then the whole point of the Bitarray is lost, which is smaller memory footprint.
Don't write a function to return a constant

You don't need uint_size(), as the returned value never changes (for a given target platform).  You can replace it with

#include &lt;climits&gt;
static const std::size_t uint_bits = CHAR_BIT * sizeof (unsigned int);


Don't require a call to init()

The constructor should fully initialize the object; just move the body of init() there instead.

Use integer operations on integers

Instead of using std::ceil to round up division, we can do this in integer arithmetic by adding one less than the divisor before dividing:

    elements_ = (bits + uint_bits - 1) / uint_bits;


Given that we know the number of bits, we can always compute the number of elements when we need it; you might consider the trade-off between storing and computing elements_.

Obey the Rule of Five (or Rule of Zero)

You allocate memory in the constructor, but don't provide copy/move constructors, nor an assignment operator, so you run the risk of double delete[].  The easiest fix is to use a standard container as the storage; you might also consider using a smart pointer to the storage.  As a last resort, you could manage the memory yourself, but I'd advise against that.

Use an unsigned type for indexing

You can avoid needing to check for negative index values by accepting an unsigned integer type in the methods.  I recommend std::size_t as the standard type usually used for that.

Return by value when possible

void size(int&amp; bits) const;


is better written as

std::size_t size() const;




My version

Working replacement code:

#include &lt;climits&gt;
#include &lt;stdexcept&gt;
#include &lt;vector&gt;

class Bitarray1D {
    using Element = unsigned int;

    class Bit {
        Element&amp; element;
        const Element mask;
    public:
        Bit(Element&amp; element, Element mask) : element{element}, mask{mask} {}
        Bit(const Bit&amp; other) : Bit{other.element, other.mask} {}
        operator bool() const { return element &amp; mask; }
        Bit&amp; operator=(bool b) { element = b ? element | mask : element &amp; ~mask; return *this; }
        Bit&amp; operator=(const Bit&amp; other) { return this-&gt;operator=(bool(other)); }
    };

    static const std::size_t element_bits = CHAR_BIT * sizeof (Element);

    std::size_t bits;
    std::vector&lt;Element&gt; array;

public:
    Bitarray1D(std::size_t bits);
    ~Bitarray1D() = default;

    std::size_t size() const;

    Bit operator[](std::size_t index);

};

Bitarray1D::Bitarray1D(std::size_t bits)
    : bits{bits},
      array{}
{
    // rounded-up division
    array.resize((bits + element_bits - 1) / element_bits);
}

Bitarray1D::Bit Bitarray1D::operator[](std::size_t index) {
        if (index &gt;= bits)
            throw std::out_of_range("Index out of range");
        return Bit(array[index / element_bits], 1u &lt;&lt; (index % element_bits));
}


int main()
{
    Bitarray1D bits{15};
    bits[0] = 0;
    bits[2] = bits[1] = 1;
    return bits[0] + bits[1] + bits[2] != 2;
}