1. Liebe Forumsgemeinde,

    aufgrund der Bestimmungen, die sich aus der DSGVO ergeben, müssten umfangreiche Anpassungen am Forum vorgenommen werden, die sich für uns nicht wirtschaftlich abbilden lassen. Daher haben wir uns entschlossen, das Forum in seiner aktuellen Form zu archivieren und online bereit zu stellen, jedoch keine Neuanmeldungen oder neuen Kommentare mehr zuzulassen. So ist sichergestellt, dass das gesammelte Wissen nicht verloren geht, und wir die Seite dennoch DSGVO-konform zur Verfügung stellen können.
    Dies wird in den nächsten Tagen umgesetzt.

    Ich danke allen, die sich in den letzten Jahren für Hilfesuchende und auch für das Forum selbst engagiert haben. Ich bin weiterhin für euch erreichbar unter tti(bei)pcwelt.de.
    Dismiss Notice

C++ Start Schwierigkeiten

Discussion in 'Programmieren' started by 0John0, Jan 27, 2009.

Thread Status:
Not open for further replies.
  1. 0John0

    0John0 Kbyte

    Zuerst ein mal :danke: für die wirklich gute und ausführlichen Unterstützung von euch


    Doch leider kapier ich das mit den Instanzen immer noch nicht.

    Vorrallem habe ich noch Mühe den class-Code zu lesen.


    PHP:
        Rechteck(int pLaengein pBreite) {
          
    laenge pLaenge;
          
    breite pBreite;
    Was genau geschieht hier?
    Ich dachte man muss eben Eigentschaften erstellen damit man die Klasse nutzen kann.

    Also zum Beispiel würde ich
    PHP:
    class Rechteck
    {      
        public:
        
        
    int laenge;
        
    int breite;    

    }
    Dann würde ich es im main() abschnitt einfach so benutzten

    PHP:
    Rechteck seite1,seite2;

    seite1.laenge 10;
    seite2.breite 20;
    Theoretisch würde das doch funktionieren?




    PHP:
    public int getFlaechenInhalt() {
          return (
    laenge breite);
        }
    Noch ne andere vielleicht etwas späte Frage:o

    Aber wohin geht dieses return ergebniss?
    Oder hat das was mit diesem getFlächenInhalt zu tun?Wird das Ergebnis automatisch in der Variable Flächeninhalt gespeichert?
     
  2. daboom

    daboom Megabyte

    Ja sorry, dieser eigentlich objektorientiert saubere Code ist für einen Anfänger vermutlich etwas overkill.

    laenge und breite in den public Teil zu schreiben, geht natürlich auch, ist aber auch etwas unsauberer. Doch dazu vielleicht auch später mehr...

    Das hier:

    Code:
    [COLOR=#000000][COLOR=#0000BB]Rechteck seite1[/COLOR][COLOR=#007700],[/COLOR][COLOR=#0000BB]seite2[/COLOR][COLOR=#007700]; 
    
    [/COLOR][COLOR=#0000BB]seite1[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000BB]laenge [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000BB]10[/COLOR][COLOR=#007700];
    [/COLOR][COLOR=#0000BB]seite2[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000BB]breite [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000BB]20[/COLOR][COLOR=#007700];
    [/COLOR][/COLOR]
    bewirkt mit Sicherheit nicht das, was Du möchtest.
    Du erstellst hier zwei Instanzen eines Rechtecks. Die eine heißt "seite1" und die andere "seite2". Dann sagst Du, dass die laenge des ersten Rechtecks 10 und die breite des zweiten 20 ist. Dabei ist dann die breite des ersten und die laenge des zweiten Rechtecks undefiniert.

    Was Du meintest wäre bestimmt folgendes:

    Code:
    [COLOR=#000000][COLOR=#0000BB]Rechteck rechteck1[/COLOR][COLOR=#007700][/COLOR][COLOR=#007700];
    
    [/COLOR][COLOR=#0000BB][/COLOR][/COLOR][COLOR=#000000][COLOR=#0000BB]rechteck1[/COLOR][COLOR=#007700][/COLOR][COLOR=#007700][/COLOR][/COLOR][COLOR=#000000][COLOR=#0000BB][/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000BB]laenge [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000BB]10;[/COLOR][COLOR=#007700]
    [/COLOR][COLOR=#0000BB][/COLOR][/COLOR][COLOR=#000000][COLOR=#0000BB]rechteck1[/COLOR][COLOR=#007700][/COLOR][COLOR=#007700][/COLOR][/COLOR][COLOR=#000000][COLOR=#0000BB][/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000BB]breite [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000BB]20[/COLOR][COLOR=#007700];[/COLOR][/COLOR]
    
    Hier wird ein Rechteck angelegt (also eine Instanz) und bei dieser werden dann laenge und breite festgelegt. In dem Zusammenhang kann man vielleicht den Konstruktor ganz gut erklären. Guck Dir mal (in Bezug auf meine Klassendefinition oben) folgendes an:

    Code:
    Rechteck rechteck1(10, 20);
    
    Das macht im Prinzip dasselbe, außer dass Du noch von Anfang an sicherstellst, dass das Rechteck vernünftig und vollständig definiert ist.
    Der Code führt automatisch den Konstruktor aus und übergibt die 10 und die 20 wie bei einem Funktionsaufruf über die entsprechenden Parameter. Da kein anderer Konstruktor definiert ist (ja, man kann mehrere Konstruktoren definieren ;)), kann man auch ein Rechteck nicht anders anlegen als auf die obige Art und Weise (Ausnahme ist noch der Copy-Konstruktor aber das ist erstmal egal...).
     
  3. 0John0

    0John0 Kbyte

    Ups:o

    Jetzt wo ich es noch mal anschaue sehe ich es auch.
    Ja klar ich habe es irgendwie verwechslet und ja ich meinte es eigentlich so wie du es danach in deinem Beispiel aufgeschrieben hast.

    PHP:
    Rechteck rechteck1(1020);
    Nun ja eigentlich ist das ja eine tolle sache,denn es ist bequemer,aber dazu habe ich 2 Fragen

    1.Woher weiss das Programm das dass 1 Argument die Länge und das 2 die Breite ist?Wird da einfach von oben nach unten gearbeitet und dementsprechend wird zugewiesen?


    2.Das funktioniert ja nun wie eine Funktion?Warum macht man denn eine Klasse und nicht gleich eine Funktion?Oder ist das ein "unübliches"Beispiel da normalerweise eine Klasse mehr kann,und wenn man aber nur dieses Rechteck braucht kann man es auf diese Weise eben bequemer schreiben?



    Das mit diesen Instanzen verstehe ich einfach nicht.Also eine Instanz ist wenn man die Klasse aufruft und etwas definiert und das ist dann eine Instanz?Also bei deinem Beispiel ist Rechteck1 eine Instanz?Und Rechteck2 wäre eine weitere Instanz?



    Nun noch eine ganz andere Frage,heute habe ich mitbekommen das die Schule welche ich im Herbst besuchen werde,nun auf Java umgestellt hat.
    Ich habe ja nun mit einem C++ Buch begonnen.Und habe es eigentlich bald durch.Nun Java anzufangen wäre nicht sinnvoll,oder?Ich habe bereits im Internet nachgeschaut und gesehen das Java z.Bsp gar kein main() Programm hat sondern nur Klassen.
    Ich weiss zwar das Java und C++ ähnlich sind,aber wie gross sind die Unterschiede?Oder merke ich gar keine, da auf der Stufe auf der ich bin die Unterschiede noch nicht so gross sind?
    In dieser Schule beginnen wir sowieso von null.


    So das sind wieder viele Fragen:rolleyes:
     
  4. daboom

    daboom Megabyte

    Dazu ziehe ich nochmal die Defintion des Konstruktors heran:

    Code:
    public Rechteck(int pLaenge, int pBreite) {
      laenge = pLaenge;
      breite = pBreite;
    }
    
    Das sollte eigentlich alles sagen ;)

    Wenn Du nun
    Code:
    Rechteck rechteck1(10, 20);
    
    schreibst, rust Du damit implizit den Konstruktor eines "neuen" Rechtecks (einer neuen Instanz) auf und die beiden Parameter 10 und 20 werden entsprechend ihrer Reihenfolge an die beiden Konstruktorparameter pLaenge und pBreite gebunden. Wie bei einer normalen Funktion.


    Das Beispiel ist vielleicht etwas zu simpel, das stimmt. Aber es ging erstmal darum, den Begriff "Instanz" zu klären, was uns ja offenbar immer noch nicht gelungen ist ;)

    "Die Klasse aufrufen" ist nicht richtig ausgedrückt. Die Klasse selbst kann man nicht aufrufen. Du meinst sicherlich den Konstruktor. Dieser wird aufgerufen, wenn eine neue Instanz erstellt wird, ja.

    Das ist vollkommen richtig.


    Nein, in Java muss natürlich auch eine main() Methode definiert werden, um ein lauffähiges Programm zu schreiben. Nur ist in Java alles in Klassen definiert, d.h. auch die main()-Methode ist eine (statische) Memberfunktion einer Klasse.

    Auf Deiner jetzigen Stufe wirst Du keine Unterschiede merken. Im allgemeinen sind diese aber auch nicht so groß, man bekommt davon erst so richtig was mit, wenn man tiefer in der Materie steckt.

    Nochmal zu den Instanzen:

    Nehmen wir mal den Typ "Integer", also "int". Ganz vereinfacht betrachtet, könnte man diesen auch als Klasse bezeichnen. Und zwar die Klasse der ganzen Zahlen von -2,1... Mrd. bis +2,1... Mrd..
    int an sich ist also noch keine Instanz, sondern nur der Bauplan für etwas. Ein sehr sehr primitiver Bauplan in dem Fall, prinzipiell ja nur ein Zahlenbereich.
    Wenn man nun beispielsweise schreibt
    Code:
    int i = 4;
    
    legt man die Instanz mit der Ausprägung "4" an. Schreibt man noch.
    Code:
    int j = 289;
    
    legt man eine weitere Instanz mit der Ausprägung "289" an. Jetzt könnte man noch
    Code:
    int k = 4; // oder auch "int k = i;"
    
    schreiben, dann hätten wir insgesamt sogar zwei Instanzen mit der gleichen Ausprägung, nämlich "4".

    So ähnlich kann man sich das bei Klassen auch vorstellen. Wenn man eine Instanz anlegt, erstellt man aber i.A. ein komplexeres Objekt.

    So, das waren jetzt wieder viele Antworten ;)
     
  5. 0John0

    0John0 Kbyte

    Yep das tut es auch,ich seh vor lauter Bäumen den Wald nicht mehr:)
    Das ist eine sehr gute Aussage,komm der Sache langsam näher
    Eh super das letzte Beispiel war sehr hilfreich!
    Ich denke ich blicke langsam durch.Oder zumindest kann ich mir nun vorstellen was der Kunstruktor und die Instanzen sind.Wenn ich mit dem Buch weiter mache und die Übungen mache werde ich es mit der Zeit sicher besser verstehen

    Ok dann bedanke ich mich mal wieder für die wirklich gute Unterstützung,und eben die nächste Frage kommt bestimmt;)
     
  6. daboom

    daboom Megabyte

    Immer ran, man hilft gern, wenn man merkt, dass die Hilfe nicht auf Granit stößt ;)
     
  7. 0John0

    0John0 Kbyte

    Man ich habe einfach Mühe diesen Code zu verstehen:aua:
    Es sollte en spezielles Beispiel im Buch darstellen,für mich zu speziell.

    PHP:
    //Beispiel_Aufgabe Kap14
    #include <iostream>
    using namespace std;

    class 
    A
    {
        
    string name;

        public:
        
    A(string n)
        {
            
    name n;
        }
        
        
    A klonen()
        {
            
    A klon("Klon von " name);
            return 
    klon;
        }
        
    string get_name()
        {
            return 
    name;
        }
    };


    int main()
    {
        
    A obj ("original");
        
    A obj2 obj.klonen().klonen().klonen();
        
        
    cout << obj2.get_name() << endl;
        
        return 
    ;
    }
    Die Ausgabe sollte sein:
    PHP:
    Klon von Klon von Klon von Original

    Aber bereits das finde ich komisch:
    PHP:
    class A
    {
        
    string name;

        public:
        
    A(string n)
        {
            
    name n;
        }
    der string "name" ist eine Eigenschaft,und diese ist private?

    Dieses "A(string n)" hier fehlt doch irgendwie was?Soll denn das eine Methode sein?Oder ist das der Konstruktor?


    Das hier ist ja das "Herzstück" des Programms:
    PHP:
    A klonen()
        {
            
    A klon("Klon von " name);
            return 
    klon;
        }
    Aber auch hier irritiert mich "A klon("Klon von " + name);
    Die Variable Klon wurde ja nirgends deklariert?Das = Zeichen fehlt irgendwie.
    Ich würde schreiben "A Klon = ("Klon von " + name);?

    Den Ablauf verstehe ich so:

    PHP:
    int main()
    {
        
    A obj ("original");
        
    A obj2 obj.klonen().klonen().klonen();
        
        
    cout << obj2.get_name() << endl;
        
        return 
    ;
    obj heisst "Original" dementsprechend auch die variable "name".
    danach erstellt man obj2 und ruft dazu die Methode "klonen()" auf.Und zwar 3x.
    Ich hätte gedacht das stehen würde "Klon von Original Klon von Original Klon von Original"
    Und das letzte
    PHP:
    cout << obj2.get_name() << endl;
    ruft einfach denk aktuellen Stand von obj2 auf.

    Ich hoffe ich habe es verständlich aufgeschrieben
     
  8. daboom

    daboom Megabyte

    Das ist der Konstruktor. Der Konstruktor wird genauso deklariert und funktioniert fast genauso wie eine normale Methode. Die zwei Ausnahmen dabei sind:

    1. Er hat keinen Rückgabetyp (vor dem "A" steht weiter nix)
    2. Er muss genauso heißen, wie die Klasse, die ihn deklariert.

    Im speziellen Fall von A, nimm der Konstruktor einen string-Parameter, womit das private Feld (Du nennst es "Eigenschaft", eigentlich heißt es aber "Member Variable" oder "Feld") "name" initialisiert wird.

    Wenn in der main also

    Code:
    A obj("original");
    aufgerufen wird, wird der Konstruktor von A aufgerufen und "original" übergeben. Das wird dann im Feld "name" gespeichert.
    Die Konsequenz ist, dass es danach eine Instanz (ja hier schon wieder das Thema ;)) der Klasse A mit dem Namen "obj" gibt, die Du dann im weiteren Code verwenden kannst.

    Dass hier kein "=" oder sowas steht, ist einfach so, sag ich mal.
    Hätte die Klasse A z.B. einen Konstruktor ohne Parameter, z.B. sowas hier:

    Code:
    A() {
      name = "Standardname";
    }
    
    Könntest Du auch einfach in der main folgendes schreiben:

    Code:
    A obj;
    
    Also ohne Klammern und dann sieht es ja fast so aus, als würde man eine Variable eines Primitivdatentyps wie "int" oder "char" anlegen.
    (In diesem Fall hätte "name" von "obj" natürlich den Wert "Standardname")



    Hier ist es genauso wie oben in der main. Nur dass nicht ein einfacher konstanter String übergeben wird, sondern einer, der sich aus dem Wert "Klon von " und dem lokalen Feld "name" zusammensetzt. Also enthält "name" der Instanz "klon" dann "Klon von " und hintendran noch "name" von der aktuellen Instanz, also genau der, bei der die Methode "klonen" aufgerufen wird.
    Die Instanz "klon" (Der Name spielt dann natürlich außerhalb der "klonen"-Methode keine Rolle mehr, sondern nur der Wert, also die Instanz) wird dann zurückgegeben (Eigentlich sogar eine Kopie davon, aber das spielt erstmal keine Rolle ;)).

    obj heißt "Original" ist ein bischen unglücklich, sagen wir, die Member-Variable "name" von "obj" hat den Wert "original".

    Nehmen wir das dreimalige Aufrufen mal auseinander:

    1. Wir rufen folgendes auf:
    Code:
    A tmpObj1 = obj.klonen();
    Jetzt hat "name" von "tmpObj1" den Wert "Klon von original". Die Methode "klonen" legt für uns die Instanz an. Dabei setzt sie einen neuen String aus "Klon von " und dem aktuellen Wert von "name" von "obj" zusammen, also in dem Fall jetzt "Klon von original".

    2. Jetzt machen wir dasgleich nochmal:
    Code:
    A tmpObj2 = tmpObj1.klonen();
    "name" von "tmpObj2" hat jetzt ein weiteres "Klon von " verpasst gekriegt, also "Klon von Klon von original".

    Das ist übrigens das gleiche, als hätten wir jetzt

    Code:
    A tmpObj2 = obj.klonen().klonen();
    
    aufgerufen.

    Wenn wir das jetzt nochmal wiederholen, kommt das aus Deinem Beispiel raus. Also mit jedem weiteren Aufruf von "klonen" kommt ein "Klon von " dazu,.

    "Den aktuellen Stand aufrufen" ist auch wieder unglücklich formuliert, es gibt lediglich den Wert der Membervariablen "name" zurück. Eine solche "getter"-Methode ist notwendig, wenn das Feld private deklariert ist, da man von außen keinen direkt Zugriff darauf hat.

    Man kann sich anfangs wahrscheinlich nicht vorstellen, warum man überhaupt etwas private macht, aber glaub mir, das hat irgendwann durchaus seine Berechtigung ;)
     
  9. 0John0

    0John0 Kbyte

    Mal wieder sehr ausführlich:)

    Aber puh ich finds trotzallem ziemlich komplex,also jetzt mit deiner Erklärung kann ich es mir etwa vorstellen wie es funktioniert aber wenn ich das jetzt selber schreiben müsste,keine Chance.


    Also der Konstrukutor ist in diesem Fall eine sehr wichtige Sache der Klasse.Ich habe gelesen der Compiler würde automatisch einen Konstruktor erstellen,das sei aber nicht optimal.

    Dadruch das ich einen Konstruktor erstelle ist es dann eben möglich

    PHP:
    A obj("original");
    so zu übergeben.
    Und eine Konstuktor ohne Parameter würde ja nicht allzu viel Sinn geben da ja "name" immer "Standardname" heissen würde?



    Das Thema Instanz habe ich mittlerweile verstanden:)
    Ich habe ich Web ein Beispiel gefunden wie du es bereits erwähnt hast,mit diesem Bauplan.Ich denke ich weiss nun was eine Instanz ist.


    Und wieder bei diesem
    PHP:
     A klonen()
        {
            
    A klon("Klon von " name);
            return 
    klon;
        } 
    man kann also in der Klasse bereits die eigene Klasse aufrufen und denn Konstruktor?

    Das heisst, hier

    PHP:
     A klonen()
        {
            
    A klon("Klon von " name);
            return 
    klon;
        } 
    kommt das hier zum Einsatz

    PHP:
    A(string n)
        {
            
    name n;
        } 
    man nennt es dann "klon" das wird dann das neue "name" und zwar setzt sich dieses dann durch "Klon von Original" zusammen?

    Ist sicher alles falsch ausgedrückt aber es geht mir im moment mehr um die Funktion:)


    Ja diese get und set Methoden hatte ich natürlich auch im Buch.Natürlich habe ich hier auch noch nicht den 100% durchblick. Aber irgendwie finde ich das noch witzig/interessant :) weil es ist eine möglichkeit zum von aussen zu zugreifen ohne gefahr zu laufen die private Werte der Klasse zu "verstellen".
     
  10. daboom

    daboom Megabyte

    Wenn es nur den einen geben würde, hast Du recht, wäre es sinnlos. Aber man kann ja mehrere Konstruktoren mit unterschiedlichen Parametern definieren. ;)

    Man ruft ja keine "Klasse" auf :rolleyes:
    Man erstellt eine Instanz dieser Klasse und dabei wird automatisch der entsprechende Konstruktor aufgerufen.
    Und: Ja das kann man auch in der Klasse selbst machen, wüsste auch nix auf Anhieb, was dagegene sprechen würde ;)


    Genau richtig.

    Sagen wir lieber "es enthält das neue "name". Sonst stimmt das soweit.

    Ich poche hier so auf die Ausdrucksweise, weil die Klasse A ja noch ein Feld "wohnort" haben könnte. Dann kann man nicht mehr so einfach sagen "klon ist das neue "name"", auch wenn ich dabei natürlich weiß, was Du meinst. In diesem Falle würde ja das Feld "wohnort" auch noch die Ausprägung der Instanz ausmachen (und nicht nur "name" allein), wenn Du verstehst wie ich meine. ;)


    Genau richtig! Das ist der Hauptgrund, warum man Membervariablen private deklariert und den Zugriff über Getter / Setter macht.
     
Thread Status:
Not open for further replies.

Share This Page