Rückgabewert?



  • Hm, genauso schreibt es mir der Compiler auch. Wie verhindere ich das nun? Muss ich mit "new" einen neune (den eigenen Datentyp) anfordern, oder muss ich den Konstruktor auf Bitvector* bv; ändern?

    Edit das im Konstruktor zu ändern ist wohl Blödsinn. Irgendwo muss ich ja mal festlegen, dass es eigentlich chars sind



  • vip@r schrieb:

    Edit das im Konstruktor zu ändern ist wohl Blödsinn. Irgendwo muss ich ja mal festlegen, dass es eigentlich chars sind

    Das ist ohnehin Blödsinn. Schau dir mal boost::dynamic_bitset an.



  • vip@r schrieb:

    Bitvector* Bitvector::createBitVector(unsigned int bits)
    {
    	bv = new unsigned char[bits/8];
    
    	for(unsigned int i=0; i<(bits/8+1); i++)
    	{
    		bv[i] = 0;
    	}
    
    //return bv;
    //return *bv;
    }
    

    Was soll das denn werden, wenn's fertig ist? Erklär mal. Dann kann man dir ggf zeigen, wie's richtig geht ...



  • TyRoXx schrieb:

    vip@r schrieb:

    Edit das im Konstruktor zu ändern ist wohl Blödsinn. Irgendwo muss ich ja mal festlegen, dass es eigentlich chars sind

    Das ist ohnehin Blödsinn. Schau dir mal boost::dynamic_bitset an.

    Er soll sich std::vector<bool> und ein bestimmtes Makro angucken.

    Aber was er jetzt wählt ist auch egal, hauptsache einen Container.



  • Ja, Container. Meine Übungsaufgabe besteht aber darin einen Bitvector mit chars nachzubauen. Versteht ihr?

    Bitvector* Bitvector::createBitVector(unsigned int bits)
    {
        bv = new unsigned char[bits/8];
    
        for(unsigned int i=0; i<(bits/8+1); i++)
        {
            bv[i] = 0;
        }
    
    //return bv;
    //return *bv;
    }
    

    Das ist eine Methode die die Klasse Bitvector zur Verfügung stellt. Diese Methode soll einen Bitvector (aneinandergereihte chars!) in Abhängigkeit von bits erstellen. Dazu hab ich aber noch einen Konstruktor entworfen:

    Bitvector::Bitvector()
    {
    	*bv = 0;
    	bits = 0;
    	byte = 0;
    }
    

    Und hier noch zur Vollständigkeit halber das header-File:

    #ifndef BITVECTOR_H
    #define BITVECTOR_H
    
    class Bitvector
    {
    private:
    	unsigned int bits;	//Anzahl der Bits im Bitvektor
    	unsigned char byte;	//chars aus denen sich der Bitvektor zusammensetzt
    	unsigned char* bv;	//pointer auf die aneinandergereihten chars
    
    public:
    	Bitvector();
    	//Bitvector(unsigned int bits);
    	~Bitvector();
    
    	Bitvector* createBitVector(unsigned int bits);
    	void printBitVector();
    
    	char getBit(unsigned int bitNr);
    	void setBit(Bitvector* bv, unsigned int bitNr);
    	void resetBit(Bitvector* bv, unsigned int bitNr);
    	Bitvector* getSlice(Bitvector* bv, unsigned int pos, unsigned int n);
    	Bitvector* addBitVector(Bitvector* s1, Bitvector* s2);
    };
    
    #endif BITVECTOR_H
    

    Mein Problem nun ist, wenn ich in der main nun eine neue Bitvector Variable erstelle und diese mit bv->createBitVector(10) erstellen lassen möchte, sagt mir der Compiler, dass bv nicht initialisiert sei.



  • vip@r schrieb:

    Bitvector* Bitvector::createBitVector(unsigned int bits)
    {
    	bv = new unsigned char[bits/8];
    
    	for(unsigned int i=0; i<(bits/8+1); i++)
    	{
    		bv = 0;
    	}
    
    //return bv;
    //return *bv;
    }
    

    Was bitte willst du denn zurückgeben? Du setzt doch nur die Membervariablen. Dafür reicht doch eigentlich ein [i]void*.

    Edit: Das BBCode-Tag [ /i] funktioniert nicht :o



  • DerCoder schrieb:

    Edit: Das BBCode-Tag [ /i] funktioniert nicht :o

    Das gibt es nicht. Du willst [/i]. Und man nimmt auch nicht das Kursiv-Tag sondern Courier .
    Außerdem, sieh dir mal die auskommentierten Zeilen an.



  • Danke Leute, ich hab das "Problem" mittlerweile selbst in Griff bekommen. Das war in der Tat trivialer als ich gedacht habe.

    Jetzt hab ich allerdings ein neues Problem mit einer Methode. Compiler sagt linker-error.

    header-Deklaration:

    Bitvector* addBitVector(Bitvector* s1, Bitvector* s2);
    

    Implementierung:

    Bitvector* addBitVector(Bitvector* bv1, Bitvector* bv2)
    {
    	//char temp = bv1->getBit(0);
    
    return 0;	//Dummy return-Wert
    }
    

    Aufruf:

    Bitvector* addition = bv.addBitVector(slice1, slice2);
    

    slice1, slice2 sind PointerVars auf einen Bitvector. Der compiler gibt mir diese fehlermeldung aus:

    Fehler	1	error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: class Bitvector * __thiscall Bitvector::addBitVector(class Bitvector *,class Bitvector *)" (?addBitVector@Bitvector@@QAEPAV1@PAV1@0@Z)" in Funktion "_main".	
    
    Fehler	2	error LNK1120: 1 nicht aufgelöste externe Verweise.
    

    Ich weiß ehrlich gesagt nich was da jetzt falsch sein soll, weil ich ja noch gar nichts in der Methode versaut haben kann. Ich hab ja noch gar nichts gecoded!



  • vip@r schrieb:

    Ich hab ja noch gar nichts gecoded!

    Und genau da duerfte dein Linkerfehler herrühren. Er findet die Funktion nicht, weil sie nicht da ist.



  • Hm, nun hab ich die Mehtode so umgeschrieben:

    Bitvector* addBitVector(Bitvector* s1, Bitvector* s2)
    {
    	char temp = s1->getBit(0);
    
    return 0;
    }
    

    Leider bekomme ich nun noch immer die Fehlermeldung. Jetzt ist die Methode aber sicherlich "sichtbar", oder?

    Edit:

    Ich bin dumm. Es fehlt die Angabe aus welchem Scope die Methode stammt! Es muss natürlich so heißen:

    Bitvector* Bitvector::addBitVector(Bitvector* s1, Bitvector* s2)
    {
    	char temp = s1->getBit(0);
    
    return 0;
    }
    


  • Hacker schrieb:

    DerCoder schrieb:

    Edit: Das BBCode-Tag [ /i] funktioniert nicht :o

    Das gibt es nicht. Du willst [/i].

    Achwas, natürlich gibt es das nicht 😉 Ich hatte angenommen, dass das einzelne Schließtag herausgefiltert wird.

    Hacker schrieb:

    Außerdem, sieh dir mal die auskommentierten Zeilen an.

    Ja, und nu? Willst du mir sagen, dass du statt der erwarteten Bitvector -Referenz, rotzfrech einen unsigned char -Pointer zurückgeben willst?

    Hacker schrieb:

    Und man nimmt auch nicht das Kursiv-Tag sondern Courier .

    Danke



  • DerCoder schrieb:

    Hacker schrieb:

    Außerdem, sieh dir mal die auskommentierten Zeilen an.

    Ja, und nu? Willst du mir sagen, dass du statt der erwarteten Bitvector -Referenz, rotzfrech einen unsigned char -Pointer zurückgeben willst?

    Was für eine Referenz? Auf jeden Fall muss er etwas zurückgeben- das ist eine factory-Methode. Google mal danach.



  • vip@r schrieb:

    Ja, Container. Meine Übungsaufgabe besteht aber darin einen Bitvector mit chars nachzubauen. Versteht ihr?

    Jepp.

    Mach's so:

    #ifndef BITVECTOR_H
    #define BITVECTOR_H
    
    #include <vector>
    
    class Bitvector
    {
    public:
        Bitvector()
        : bits(0)
        {}
    
        explicit Bitvector(unsigned int bits);
    
        unsigned int size() const
        { return bits; }
    
        int getBit(unsigned int index) const;
    
        void setBit(unsigned int index);
        void resetBit(unsigned int index);
    
        void setBit(unsigned int index, int to_value)
        { if (to_value) setBit(index); else resetBit(index); }
    
    private:
        unsigned int bits;
        std::vector<unsigned char> data;
    };
    
    #endif BITVECTOR_H
    

    Die Semantik von slice und addbitvector ist mir allerdings nicht ganz klar, habe ich deswegen weggelassen. Was auch vielleicht nicht sofort auffällt: Ich fügte hinter getBit ein const ein.

    in der cpp-Datei entsprechend noch den Konstruktor, getBit(unsigned), setBit(unsigned) sowie resetBit(unsigned) implementieren.



  • Für eine Factory-Methode sollte diese aber 'static' sein.

    Ansonsten sieht es mir eher so aus, als ob einfach 'this' zurückgegeben werden soll. Aber das ist natürlich logisch völliger Blödsinn, denn zum Erzeugen sollten man ja den (bisher auskommentierten) Konstruktor benutzen.

    Und auch die Methoden 'setBit' und 'resetBit' haben überflüssigerweise den 'Bitvector *' als Parameter (anstatt auf 'this' intern zu arbeiten).

    Daher die Frage an vip@r: hast du das Klassendesign selber erstellt oder wurde es dir so gegeben (und du sollst nur die Funktionen ausprogrammieren)?



  • Danke für eure Antworten! Ich hab mir diese factory-Methoden mal durchgesehen. Ich werde mir das wenn mal Zeit ist genauer anschaun. Da das in meiner Schule gar nicht gelehrt wurde.

    Ich hab jezt übrigens ein weiteres Problem:

    Ich soll jetzt noch eine binäre Addition von zwei solchen Bitvektoren coden. Vorzustellen hat man sich das so:

    Ich hab einen Bitvektor s1 und einen Bitvektor s2 und das sind ja eigentlich char*. Ich soll die jetzt binär addieren. Wie die binäre Addition schriftlich geht (Übertrag usw.) ist mir natürlich klar. Wie ich das aber jetzt Softwaretechnisch umsetzen soll ist mir nicht ganz klar. Könnt ihr mir da helfen?

    Ich hab mal versucht das soweit umzusetzen:

    Bitvector* Bitvector::addBitVector(Bitvector* s1, Bitvector* s2)
    {
    	unsigned char maske = 1;
    
    	for(unsigned int i=((s1->bits) / 8) + 1; i>0; i--)
    	{
    		s1->bv[byte-1];   //Adressierung des richtigen Bytes
    		s2->bv[byte-1];   //Adressierung des richtigen Bytes
                    //falls der bitvektor aus mehreren chars besteht, muss ich ja beim hintersten anfangen und diese 
                    //äußerste for-Schleife schaltet mir quasi die bytes durch
    		for(unsigned int j=s1->bits; j>0; j--)   //in bits steht die Anzahl der gesetzten und notwendigen Bits von s1
    		{
                        maske = maske << 1;		//Auswahl des Bits
    		}
    
                    for(unsigned int j=(s2->bits); j>0; j--)
    		{
    			maske = maske << 1;		//Auswahl des Bits
    		}
                    //die maske soll mir die einzelnen Bits maskieren.
                    //Wie aber mache ich das dann konkret weiter? Ich mein, ich muss ja s1 und s2 "verunden"
                    //wie regle ich den zusätzlichen Übertrag, der an vorderster Stelle komt?
    	}
    
    return 0;
    }
    

Anmelden zum Antworten