AnsiString = AnsiString funktioniert nicht!?



  • was ich meine ist, daß 'AnsiString Old;' so nicht NULL ist !

    mach doch einfach folgendes:
    scheibe direkt vor der Zuweisung 'Old = Symbol1;'

    ShowMessage("Old = " + Old + "\nSymbol1 = " + Symbol1);
    Old = Symbol1;
    

    dann siehst Du welche Werte die Variablen besitzen.
    ShowMessage ist manchmal der beste Debugger den es gibt, gerade für soetwas.

    edit:

    Du brauchst auch nur vor der Zuweisung einen Haltepunk zu setzten und mit der Maus über die Variablen zu gehen.



  • Hallo,

    Welchen Builder verwendet ihr denn? Beim 2007er ist es häufig so, dass selbst im Debug-Modus Variablen rausoptimiert werden können. Da geht ihr dann am besten mal in die Options Punkt Optimierungen und schaltet dort alle verbliebenen Optimierungen ab.



  • ich gehe mal davon aus, daß er den 6er meint, da er ja zu diesem Zeitpunkt geschrieben hatte, die 7er funktioniert bei ihm nicht und der 6er gefällt ihm bei weiten besser.



  • Sorry, konnte nicht früher schreiben (Schule)

    OldMan00 schrieb:

    ich gehe mal davon aus, daß er den 6er meint, da er ja zu diesem Zeitpunkt geschrieben hatte, die 7er funktioniert bei ihm nicht und der 6er gefällt ihm bei weiten besser.

    Ja genau, benutze BCB 6, habe nun auch mit ShowMessage(Old); den String ausgegeben, das Fenster zeigt aber nichts an (also wie im Debugger angezeigt).

    Vielleicht mach ich ja einen Denkfehler

    Hier nochmal das Wichtigste meines Programms:

    const.h:

    AnsiString Symbol1; //gloable Deklaration
    

    Konstrukter der Form1:

    Symbol1 = "images\\circle.bmp"; //(relativer) Pfad des Bitmaps, welches standardmäßig geladen wird
    

    OnClick-Ereignis eines Images in der TChangeSymbol-Form:

    void __fastcall TChangeSymbol::Image4Click(TObject *Sender)
    {
            AnsiString Old;
            if(RadioButtonP1->Checked)
            {
                    //change symbol of player1
                    Old = Symbol1;
                    //change the old symbols to the new one:
                    change_symbols(Old,Symbol1);
            }
            //[...]
    }
    

    Nun der eigentliche Sinn ist es, dass der User das Bild, welches er als Logo haben will, auswählen kann. Im aktuellen Spiel sollte man das alte Spielfeld dann durch die neuen Symbole ersetzen, dadurch muss jedoch auch das alte Symbol bekannt sein (da nicht alles die gleichen Felder sind). Ja das wär's, ich weiß es gäbe auch andere Methoden, aber das hier ist wohl die einfachste, indem ich später die AnsiStrings Old und die gespeicherten im Spielfeld überprüfe und falls notwendig ersetze

    Ja es funktioniert leider nicht, ansonsten wird Old aber auch nirgends verändert!?

    Hilfe, Abgabetermin ist in einer Woche!



  • Hast Du in der Deklaration von TChangeSymbol noch ein zweites Symbol1?



  • witte_ schrieb:

    Hast Du in der Deklaration von TChangeSymbol noch ein zweites Symbol1?

    Nein auch nicht. Hab auch schon Symbol1 umbenannt (und natürlich überall wo es vorkam), zeigt aber immer noch denselben Fehler!



  • void __fastcall TChangeSymbol::Image4Click(TObject *Sender)
    {
            AnsiString Old;
            if(RadioButtonP1->Checked)
            {
                    //change symbol of player1
                    ShowMessage(Symbol1);
                    Old = Symbol1;
                    ShowMessage(Old);
                    //change the old symbols to the new one:
                    change_symbols(Old,Symbol1);
            }
            //[...]
    }
    

    Was gibt dir dieser Quelltext in der ersten bzw. zweiten Box aus?



  • OK, habs jetzt endlich fertig!

    Ich weiß nicht genau an was es lag, hab mehrere Änderungen durchgenommen:
    - Include-Guards (bei den Konstanten) hinzugefügt
    - aus konstanten AnsiStrings variable gemacht (werden natürlich nicht verändert)
    das hat nämlich immer zu Linker-Errors geführt 😮 (Einbindung der Variablen in der Header mittels extern

    Nochmal durch Debuggt und plötzlich ging die Zuweisung 😮
    Wahrscheinlich lag es an den nicht vorhandenen Include-Guards (achtet immer auf die Linker-Warnungen)

    Auf jedenfall funktioniert es nun 🙂



  • Das ist halt das Problem mit globalen Variablen. Da tauche derartige Dreckeffekte immer mal wieder auf. Eigentlich ist das ein deutliches zeichen dafür sein Design zu überdenken. 🙂



  • Braunstein schrieb:

    Das ist halt das Problem mit globalen Variablen. Da tauche derartige Dreckeffekte immer mal wieder auf. Eigentlich ist das ein deutliches zeichen dafür sein Design zu überdenken. 🙂

    Ja aber gehört es auch zum guten Programmierstil seine Konstanten nicht global zu definieren? Ich meine hier sind nicht alles Konstanten okay versteh ich, im nächsten Projekt werde ich das anders machen. Aber wenn die Konstanten von (fast) allen Forms gebraucht werden, sollte man dann auch nicht global deklarieren?



  • Bei Konstanten kann man das schon so machen. Ich bevorzuge hier aber eher eine struct in der alle diese Konstanten zusammengefasst werden. Die lege ich dann in einen Singleton ab.
    Bei performancekritischen Programmteilen arbeite ich aber auch mit extern.
    Ich hatte hier irgendwie nicht gesehen, dass es sich um globale Konstanten handeln soll (kein const).



  • Braunstein schrieb:

    Bei Konstanten kann man das schon so machen. Ich bevorzuge hier aber eher eine struct in der alle diese Konstanten zusammengefasst werden. Die lege ich dann in einen Singleton ab.
    Bei performancekritischen Programmteilen arbeite ich aber auch mit extern.
    Ich hatte hier irgendwie nicht gesehen, dass es sich um globale Konstanten handeln soll (kein const).

    Es waren auch nicht alle global (z.B. Symbol, Symbol2), aber z.B. triangle,cross,... waren globale AnsiStrings. Diese habe ich früher auch als konstant (const) deklariert, durch das extern wollte mir der Linker das aber nie abnehmen (auch wenn ich extern const AnsiString... schrieb). Er brachte immer eine Linker-Error z.B. Undefined Symbol _triangle (mit Unterstrich). Ich habe nun zu Testzwecken das const entfernt und da nur ich an diesem Projekt arbeite, auch darauf geachtet sei nirgends zu verändern (ich weiß, kein guter Programmierstil, aber wenn der Linker nicht mitspielt)



  • extern const AnsiString ist kein Problem. Wenn dein Linker da nicht mitspielt hast du was anderes falschgemacht.



  • Braunstein schrieb:

    extern const AnsiString ist kein Problem. Wenn dein Linker da nicht mitspielt hast du was anderes falschgemacht.

    Ja aber wenn ich sie nicht konstant deklariere funktioniert alles, wenn ich alles auf const umändere:
    const.h:

    const AnsiString triangle = "images\\triangle.bmp";
    

    Unit2.cpp:

    extern const AnsiString triangle;
    

    Das führt zu folgendem Linkererror:

    [Linker Fehler] Unresolved external '_triangle' referenced from K:\TICITACTOE\TICITACI6\UNIT2.OBJ
    

    da ist wohl ansonsten nichts falsch, oder schon? Ach ja, const.h wird in Unit1.h inkludiert, ebenso Unit2.h



  • Du machst es ja auch genau verkehrt rum. Das

    extern const AnsiString triangle;
    

    gehört in den Header und die Definition in eine cpp.



  • Braunstein schrieb:

    Du machst es ja auch genau verkehrt rum. Das

    extern const AnsiString triangle;
    

    gehört in den Header und die Definition in eine cpp.

    Ja aber ich definiere die AnsiStrings in meinem Header const.h, wo sie ihren (konstanten) "Wert" zugewiesen bekommen. Somit ist das praktisch einfach eine normale Header-Datei.
    Aus der Unit1 rufe ich dann die Unit2 auf, in welcher ich nun mittels extern diese AnsiStrings "einbinde". Wenn ich die extern-Deklaration in den Header der Unit2 schiebe, bleibt es bei den selben Linker Errors.



  • Hallo

    Braunstein hat schon recht. Probier es doch einfach mal aus.

    bis bald
    akari





  • Ich glaube ich steh gerade auf der Leitung

    In meinem Buch steht:

    The extern specifier tells the compiler that the following
    variable types and names have been declared elsewhere. In other words, extern lets the compiler know what the types and names are for these global variables without
    actually creating storage for them again. When the two modules are linked, all
    references to the external variables are resolved.
    

    Braunstein schrieb:

    Du machst es ja auch genau verkehrt rum. Das

    extern const AnsiString triangle;
    

    gehört in den Header und die Definition in eine cpp.

    Ich habe nun auch versucht die extern-Deklarationen in die Unit2.h zu packen mit demselben Ergebnis. Die Definition meiner AnsiStrings findet in der const.h statt, sollte ich das nun in eine cpp umwandeln? -Wie gesagt, ich steh gerade auf der Leitung



  • Nein. extern sagt dem Compiler, dass eine Variable dieses Namens existiert und irgendwo auch definiert wird. Damit die Variable in deinem Programm bekannt gemacht werden kann, packst diese extern Deklaration in einen Header.
    Die dazu gehörige Definition packst du in irgendeine cpp damit der Linker sie auch findet.


Anmelden zum Antworten