2 votes

Opérateurs bitarray [] et d'affectation personnalisés

Je suis en train de créer une classe bitarray pour un projet GA sur lequel je travaille. Je me demande s'il n'y a pas une meilleure façon de faire en sorte que mon opérateur [] fasse des affectations que celle que j'ai trouvée. Pour l'instant, la version non-const de l'opérateur renvoie une classe secrète "bitsetter" par valeur, ce qui semble un peu excessif. Je ne peux certainement pas retourner un bit par référence, mais je me demande s'il n'y a pas une meilleure façon (c'est-à-dire plus concise, plus efficace). Merci d'avance. Pardonnez mon throw 0 . Totalement un placeholder ;)

class bitsetter
{
public:
    short ind;
    unsigned char *l;

    bitsetter & operator=(int val)
    {
        int vs = 1<<ind;
        if( val==0 ) {
            vs = ~vs;
            *l = *l & vs;
        }
        else
        {
            *l = *l | vs;
        }
        return *this;
    }

    int value() const
    {
        return ((*l)>>ind)&1;
    }

    friend std::ostream & operator << ( std::ostream & out, bitsetter const & b )
    {
        out << b.value();
        return out;
    }

    operator int () { return value(); }
};

class bitarray
{
public:
    unsigned char *bits;
    int size;

    bitarray(size_t size)
    {
        this->size = size;
        int bsize = (size%8==0)?((size+8)>>3):(size>>3);
        bits = new unsigned char[bsize];
        for(int i=0; i<size>>3; ++i)
            bits[i] = (unsigned char)0;        
    }

    ~bitarray()
    {
        delete [] bits;
    }

    int operator[](int ind) const
    {
        if( ind >= 0 && ind < size )
            return (bits[ind/8] >> (ind%8))&1;
        else
            return 0;
    }

    bitsetter operator[](int ind)
    {
        if( ind >= 0 && ind < size )
        {
            bitsetter b;
            b.l = &bits[ind/8];
            b.ind = ind%8;
            return b;
        }
        else
            throw 0;
    }
};

2voto

GManNickG Points 155079

Il s'agit de l'approche standard, appelée mandataire . Notez qu'il est généralement défini dans la classe elle-même :

class bitfield
{
public:
    class bit
    { };
};

En outre, il est un peu plus "sûr" :

class bitfield
{
public:
    class bit
    {
    public:
        // your public stuff
    private:
        bit(short ind, unsigned char* l) :
        ind(ind), l(l)
        {}

        short ind;
        unsigned char* l;

        friend class bitfield;
    };

    bit operator[](int ind)
    {
        if (ind >= 0 && ind < size)
        {
            return bit(&bits[ind/8], ind % 8);
        }
        else
            throw std::out_of_range();
    }
};

Ainsi, les gens n'ont accès qu'à l'interface publique de bit et ne peuvent pas créer leur propre interface.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X