public-Frage



  • Hi!
    Du hast ja die Frage dir schon selbst beantwortet. Wenn du ein Attribut in einer Klasse als public deklarierst, kannst du mit jeder Instanz von dieser Klasse darauf zugreifen. Was natürl. Schwachsinn ist!

    optimaler wäre:

    class test{
       //private
       int var;
    
       public int GetVar() {
         //gebe den wert der var. zurück
       }
    }
    


  • Original erstellt von grenouille:
    Hi!
    Du hast ja die Frage dir schon selbst beantwortet. Wenn du ein Attribut in einer Klasse als public deklarierst, kannst du mit jeder Instanz von dieser Klasse darauf zugreifen. Was natürl. Schwachsinn ist!

    Ähm... Vielleicht erklär das mal ausführlicher, am besten mit einem Code Beispiel. Sonst wissen wir nicht, was daran falsch ist 😉

    Wenn ein Attribut einer Klasse public -> mit jeder Instanz der Klasse darauf zugreifen

    Eine Instanz hat immer auf alle ihre Variablen Zugriff. Eine Instanz hat eine eigene Variable, wenn nicht static im Spiel ist.
    Also, bitte erklär mal, damit ich dich auch verstehe.

    Übrigens: dein Codebeispiel sieht nach Java aus
    So in C++:

    class test {
      //private
      int var1, var2;
    
    public: //hat den sinn, gleich mehrere funktionen auf einmal public zu deklarieren
    //sowas wie in java gibt es nicht
      int GetVar1 () const { return var1; }
      int GetVar2 () const { return var2; }
    };
    


  • Nochmal zum OP:

    struct CharPtrInStruct {
       const char *bspText;
    };
    
    //bzw als class:
    /*
    class CharPtrInClass {
    public: 
       const char *bspText;
    };
    */
    
    int main () {
      CharPtrInStruct test;
      test.bspText = "Hello"; //greife schreibend auf den zeiger zu
      test.bspText = "World"; //dito
    
      char c[6]; 
      strcpy (c, test.bspText); //und lesend
    
      cout << test.bspText[1] << '\n'; //gibt aus: 'o' (von World)
    }
    
    //anm. das const char nur wegen den const char* strings, die ich dem zuweise
    

    Jetzt ist bspText public und der Inhalt kann von überall aus gesehen werden (voraussetzung ist natürlich eine instanz)
    Hilft das? Wenn nicht, erklär mehr



  • Eine Instanz hat immer auf alle ihre Variablen Zugriff. Eine Instanz hat eine eigene Variable, wenn nicht static im Spiel ist.
    Also, bitte erklär mal, damit ich dich auch verstehe.

    test* obj = new test(2,4);
    int wert = obj->var1;
    

    das funktioniert bestimmt nicht!

    Tschuldigung das es wischiwaschi Code war, es sollte ja nur das Prinzip aufzeigen.



  • **
    das funktioniert bestimmt nicht!
    **

    Doch, so:

    class test {
      int var1, var2;
    public:
      test (int a, int b) : var1(a), var2(b) {}
      void geht_doch ();
    };
    
    void
    test::geht_doch () {
       test *obj = new test(1,2);
       obj->var1 = 42;
    
       delete obj;
    }
    
    int main () {
       test obj;
       //obj.var1 = 10;  - das geht tatsächlich nicht
       obj.geht_doch ();
    }
    

    es kommt eben auf den kontext an. alle instanzen einer klasse haben immer zugriff auf alle variablen anderer instanzen derselben klasse.

    [ Dieser Beitrag wurde am 07.07.2003 um 22:36 Uhr von davie editiert. ]



  • Also das Problem scheint jetzt behoben zu sein. Bekomme keine Fehler mehr beim Compilieren.

    Erklärung:
    Von einer Klasse wird char* bspText an eine Funktion einer anderen Klasse übergeben.

    Bsp:

    1. Main.cpp:
    char *bspText; 
        ...// bspText bekommt Inhalt zugewiesen.
        ...
        SHFile shf;
    
        isOk = shf.loadFunktion1(bspText)   //Übergabe bspText
    
    1. SHFile.cpp
    bool SHFile::loadFunktion1(char* sText) //sText entspricht bspText
        {
            ...
            xyInhalt = sText;   //ab hier kann in jeder Funktion dieser Klasse mit dem Inhalt gearbeitet werden
            ...
        }
    
    1. SHFile.h
    ...
        public:
            char *xyInhalt;
        ...
    

    Ich weiß nicht, ob das die sauberste Lösung ist, was meint Ihr?



  • wieso in SHFile.h public?
    Mal den kompletten Code (soweit er bekannt ist):

    class SHFile {
    public:
      char *xyInhalt;
      bool loadFunktion1 (char *text) {
        xyInhalt = text;
      }
    };
    
    int main () {
      char bspText[] = "Forty-Two";
      SHFile shf;
      shf.loadFunktion1 (bspText);
    
      //und - so weit mir dein Problem klar ist:
      char *x = shf.xyInhalt;
    }
    

    So?
    Generell kann man sagen, dass öffentliche Datenmember schlecht sind.
    Man macht dann getter/setter Funktionen, um den Zugriff auf sie noch unter Kontrolle zu halten. Zum Beispiel ein

    const char * getInhalt () const { return xyInhalt; }
    


  • mach das Attrribut char *xyInhalt privat.
    Würde lieber Strings verwenden, sind typensicherer und auch C++ und kein C.



  • Hi!

    @davie @grenouille:

    Würde lieber Strings verwenden, sind typensicherer und auch C++ und kein C.

    Info:
    Also dieses char *bspText (sowie einige andere char* bspText2, bspText3 etc.) erhalte ich aus einem externen Programm und muß sie nun in meiner DLL bearbeiten. Aus meiner Main.cpp leite ich es dann weiter an die Funktion

    bool SHFile::loadFunktion1(char* sText, char* sText2, char* sText3,...)

    die wiederum viele andere Funktionen aufruft, die diese Inhalte (je nach Bedarf) benötigen.

    @grenouille:

    Würde lieber Strings verwenden, sind typensicherer und auch C++ und kein C.

    Ich habe in diesem Forum und auch in anderen schon viel über char* und std::string-Konvertierungen gelesen, wie gefährlich ein umcasten ist etc. Aus diesem Grunde habe ich mich entschieden bei char* zu bleiben, aber um ehrlich zu sein, es ist viel schwieriger damit zu arbeiten als mit einem std::string.

    @davie:

    Man macht dann getter/setter Funktionen, um den Zugriff auf sie noch unter Kontrolle zu halten. Zum Beispiel ein

    const char * getInhalt () const { return xyInhalt; }

    Kannst Du das ein wenig näher erläutern?
    Danke!



  • Aber klar! Doch vorher:
    Sicher, ein Umcasten von char* nach string à la

    const char *x = "Hello World";
    std::string str = (std::string) x;
    

    würde knallhart danebengehen..

    aber ein umwandeln macht nix:

    const char *x = "Hello World";
    std::string str(x); //ist niemals ein Problem
    

    OK, jetzt zu den gettern/settern.
    Eine übliche Technik, um öffentliche Variablen zu vermeiden, ist es, einer Klasse sogenannte getter- und setter-Methoden zur Verfügung zu stellen. Über diese darf dann die "Außenwelt" (also alles außerhalb der Klasse) die betreffende Elementvariable geregelt verändern.
    Bsp.:

    class bsp {
      int x; //privat
    public:
      void set_x (int neuer_wert) { x = neuer_wert; }
      int get_x () const /*hier ein const, weil der aufruf von get_x die klasse ja nicht verändert (const-correctness)
      { return x; }
    };
    

    So kannst du von außerhalb einer Klasse auf x zugreifen, ohne es direkt anzusprechen.
    Zu diesem Thema gibt es sicher schon sehr viele Threads und vielleicht steht bei den FAQs auch etwas dabei.



  • Original erstellt von <Torben>:
    Kannst Du das ein wenig näher erläutern?

    bsp:

    du hast ne klasse Auto:

    class Auto
    {
    public:
      int maxSpeed;
      int currentSpeed;
    
      Auto() : maxSpeed(150), currentSpeed(0) {}
    };
    

    jetzt kann jemand lustiger herkommen und

    Auto car;
    car.maxSpeed=100;
    car.currentSpeed=200;
    

    schreiben. doch das wollen wir nicht.
    es ist zwar moeglich, dass ein auto zB einen berg hinunter rollt und dann schneller rollt als es fahren kann, aber dass wollen wir mal ausser acht lassen (bzw. kann der lustige user statt 200 ja auch 1000000 schreiben - und dann IST es zu schnell :p)

    nunja, das laesst sich leider nicht pruefen 😞 der user kann nen currentSpeed hoeher als maxSpeed haben, das wollen wir aber nicht:

    class Auto
    {
    private:
      int maxSpeed;
      int currentSpeed;
    
    public:
      Auto() : maxSpeed(150), currentSpeed(0) {}
    
      void setSpeed(int newSpeed)
      {
        if(newSpeed>maxSpeed)
          throw logic_error("too fast"); //melde fehler
    
        currentSpeed = newSpeed;
      }
    
      int getSpeed() const
      {
        return currentSpeed;
      }
    };
    

    und schon kann das auto nicht mehr zu schnell fahren.
    jetzt koennen wir sogar einen schritt weiter gehen und sagen: die interne darstellung ist fuer den anwender egal.

    wir koennten auto intern aendern, ohne dass es der anwender bemerkt:

    class Auto
    {
    private:
      int maxSpeed;
      float currentSpeedPercent;
    
    public:
      Auto() : maxSpeed(150), currentSpeedPercent(0) {}
    
      void setSpeed(int newSpeed)
      {
        if(newSpeed>maxSpeed)
          throw logic_error("too fast"); //melde fehler
    
        currentSpeedPercent = static_cast<float>(newSpeed)/maxSpeed*100;
      }
    
      int getSpeed() const
      {
        return ceil(currentSpeedPercent*maxSpeed/100);
      }
    };
    

    und wir haben die interne darstellung vollkommen unabhaengig von der schnittstelle gemacht. das ist mit public membervariablen natuerlich nicht moeglich.

    man muss sich jetzt nur noch fragen ob ein increaseSpeed(int) und decreaseSpeed(int) nicht sogar besser waeren als das setSpeed() - aber der hintergedanke bleibt gleich:
    verstecke die implementationsdetails sogut du kannst!


Anmelden zum Antworten