Klasse Bitarray



  • Hallo zusammen,

    class cbit
    {
    	int a;
    
    public:
    	cbit(int b){
    		a=0;
    		a|=1<<b;
    	};
    	cbit(){
    		a=0;
    	};
    [..]
    	void operator[](int& b)
    	{
    //	was brauch ich hier?
    	};
    
    };
    
    int main()
    {
    	cbit a(3);
    	a[1]=0;
    	a[2]=1;
    
    }
    

    Ich möchte also ein Bitarray erstellen, darauf aber auch einfach mit den eckigen Klammern drauf zugreifen und setzen. Ich mein, ich weiß gar nicht, ob das überhaupt geht, das Problem ist ja, ich brauch ja eigentlich ne Rückgabe für die Zuweisung. Hab ich überhaupt ne Chance?

    Viele Grüße,

    Mata



  • class cbit  {
    private:
        int a;
    
    public:
        cbit ( int b ) : a ( 0 ) {
            a |= 1 << b;
        };
        cbit () : a ( 0 ) {};
    
      class Proxy  {
      private:
        int array;
        char index;
    
      public:
        Proxy ( int& _array, const char _index ) : array ( _array ), index ( _index ) {};
    
        const Proxy& operator= ( const bool value )  {
          if ( value )
            array |= value << index;
          else
            array &= ( array >> index ) ^ 1;
        };
      };   
    
    [..]
        Proxy& operator[] ( const char b )  {
          return Proxy ( a, b );
        };
    
    };
    
    int main()  {
        cbit a ( 3 );
        a [ 1 ] = 0;
        a [ 2 ] = 1;
    };
    

    ich habe so das gefuehl, dass der Proxy::operator= falsch implementiert ist, aber bitopertionen sind nicht meine staerke 🙂

    was auch immer



  • Hi,

    also deine Lösung funzt nicht. Das Problem ist folgendes:

    Du gibst in operator[] ne Referenz auf die Variable zurück, die aber doch am Ende der Methode wieder gelöscht wird. Dann wird operator= von proxy aufgerufen, dort steht dann irgend n quark in array und index, der ändert die, und das wars.

    Selbst wenn man das mit der Rückgabe noch korrigiert auf proxy und nicht proxy&, dann ändert sich aber doch in der klasse proxy immer noch nix an meinem eigentlichen bitvektor.

    Ich hab ein bisschen hin und her überlegt an deiner Idee, aber eigentlich muss doch operator[] auf jeden fall n cbit& zurückgeben, damit sich das a (mein Bitvektor) überhaupt noch ändern kann, oder?

    Ich habs mal etwas anders gemacht, tuts, find ich aber doof, deine Version an sich wäre ja eleganter, wenn mans irgendwie so machen kann.

    #include <stdio.h>
    
    class cbit
    { 
        int a; 
    	int merk;
    
    public: 
    	cbit (int b) : a(0), merk(-1)
    	{ 
    		a |= 1 << b; 
    	}; 
    
    	cbit () : a(0), merk(-1)
    	{}; 
    
    	cbit& operator[] (const char& b)
    	{
    		merk=b;
    		return *this;
        }; 
    
    	cbit& operator= (const char& b)
    	{
    		if (merk!=-1)
    			if (b)
    				a|=1<<merk;
    			else
    				a&=~(1<<merk);
    
    		merk=-1;
    		return *this;
        }; 
    
    	void ausgabe()
    	{
    		printf("%i\n",a);
    	};
    
    }; 
    
    int main()  { 
        cbit a (3); 
    	a.ausgabe();
        a[2] = 1; 
    	a.ausgabe();
        a[2] = 0; 
    	a.ausgabe();
    };
    


  • Das ist nicht so ganz ohne: Am besten ihr baut cbit erstmal so, daß man mit set(int pos, bool value) das Bit an Position pos auf value stellen kann.

    Proxy sieht dann ungefähr so aus:

    class Proxy
    {
    public:
     // Referenz auf den Container halten und die Position merken, auf die wir referenzieren
     Proxy(cbit & bits, int pos) : bits_(bits), pos_(pos) {}
    
     // einfach das entsprechende bit, auf das sich dieser Proxy bezieht einstellen
    bool operator= (bool value) { bits_.set(pos, value); }
    
     // implizite Konvertierung nach bool
      operator bool() { return bits_.get(pos); }
    
    private:
      int pos_;
      cbit & bits_;
    }
    

    Und nicht vergessen, auch den operator[](int) const in cbit zu überladen. Da genügt dann eine einfache Rückgabe von bool.

    MfG Jester

    edit1: kleine Korrektur

    edit2: Für kongruedi könntet ihr natürlich statt int auch std::size_t benutzen. 🙂



  • to mata

    hast du gesehen, wie es in std::vector<bool> functioniert? das ist genau, was du brauchst.



  • So, denke, das hab ich geschnallt, dank dir, jester. Nur deinen Kommentar bezüglich operator[](int) const überladen versteh ich nicht, warum? Und, ich behalte int ;).

    2 ssm: Naja, keine Ahnung, ich wollt das Rad eben nochmal neu erfinden :-).



  • Naja, wenn Du nur den op[] so überlädst, dann kannst Du nicht mit

    op[] auf ein const cbit zugreifen, da dem Proxy ja eine cbit &, keine cbit const& übergeben wird. Die kriegst Du aber im const-Falle nicht. Daher mußt Du diese Variante gesondert behandeln.

    const cbit x(blabla);
    
    bool b = x[5]; // kompiliert nicht, wenn keine const-Version des op[] zur Verfügung steht.
    

    MfG Jester


Anmelden zum Antworten