Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » c++ Aggregation

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
25.01.2018, 17:04 Uhr
SaBit



moin,
ich schreibe gerade ein Beispielprogramm um das mit Aggregation über Zeiger-Attribut und Komposition über interne Daten zu verstehen. Nur leider funktioniert es gerade nicht weil ich gegenseitig die Header Datei include. Ich weiss es allerdings auch nicht besser..


C++:
//Lehrer.h
#include "Schule.h"
#include "Klasse.h"
class Lehrer{
public:
Schule *pschule;
Klasse *pklasse;
void Vorstellung();
};

//und Schule.h
#include "Klasse.h"
#include "Lehrer.h"
class Schule{
public:
char *pname;
Klasse klassen[4];
Lehrer *pLehrer[8];
};



wie kann ich das umgehen?
Danke schonmal!

Dieser Post wurde am 27.01.2018 um 17:46 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
25.01.2018, 22:24 Uhr
TOSHMAX



Das funktioniert mit einer "forward declaration" (Vorwärtsdeklaration im Deutschen?), siehe z. B. hier:
http://en.cppreference.com/w/cpp/language/class#Forward_declaration

Damit weiß zwar z. B. eine Schule nicht genau was ein Lehrer eigentlich ist oder was er kann, aber sie weiß, dass es eine Klasse ist und kann zumindest darauf zeigen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
26.01.2018, 09:41 Uhr
ao

(Operator)



C++:
// Lehrer.h

// Forward-declarations,
// ausreichend für alles,
// was über Pointer oder Referenzen
// "aggregiert" wird
class Schule;
class Klasse;

class Lehrer
{
    Schule * pschule;
    Klasse * pklasse;
};


// Schule.h

// Forward-declaration (siehe Lehrer.h)
class Lehrer;

// Klasse.h muss inkludiert werden,
// weil class Klasse in Gänze benötigt wird,
// weil die Schule ihre Klassen nicht
// aggregiert, sondern daraus "komponiert" ist.
#include "Klasse.h"

class Schule
{
    Lehrer * plehrer[8];
    Klasse klassen[4];
};
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
27.01.2018, 16:46 Uhr
SaBit



Danke Thosmax!!
ja, für eine Assoziation war das Beispiel nicht so toll gewählt, aber die Klassen sollten auch unabhängig von der Schule existieren..
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
28.01.2018, 17:31 Uhr
ao

(Operator)


Aber so wie es hier definiert ist (ein Array von Klassen als "einkomponierte" Member von Schule) existieren die Klassen gerade nicht unabhängig von der Schule ...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
28.01.2018, 18:46 Uhr
SaBit



ok, aber die schule exestiert ohne die lehrer.
ich wusste einfach das mit der extra zeile class Schule nicht.
dankeschön!

nächstes Beispiel:


C++:
/******************************************************************************

                              Online C++ Compiler.
               Code, Compile, Run and Debug C++ program online.
Write your code in this editor and press "Run" button to compile and execute it.

*******************************************************************************/


#include <iostream>

using namespace std;

class Zimmerpflanze{
        public:
        float groesse;
        int maxgroesse;
        bool giftig;
};

class Ficus : public Zimmerpflanze{
        public:
        Ficus(float g)
        {maxgroesse=300;
        giftig=0;
        groesse=g;}
        float PreisBerechnen(){
           return (5+10*groesse);
        }
};

class LuxusFicus : public Ficus{
};

int main()
{
    Ficus F1(1.20);
    F1.PreisBerechnen();
    LuxusFicus L1;
    L1.PreisBerechnen();
    
    
    cout << "Ficus Preis : " << F1.PreisBerechnen() << endl;
    cout << "Luxus Preis : " << F1.PreisBerechnen() << endl;

    return 0;
}



Die Fehlermeldung ist:
main.cpp: In function 'int main()':
main.cpp:38:16: error: use of deleted function 'LuxusFicus::LuxusFicus()'
LuxusFicus L1;
^

das verstehe ich nicht. ich hab die klasse doch vererbt und nicht gelöscht. an was liegt es?
ich will später das mit dem virtual noch üben. also das, mit der funktion, ist kein fehler sondern gewollt xD

Dieser Post wurde am 28.01.2018 um 18:47 Uhr von SaBit editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
29.01.2018, 10:07 Uhr
ao

(Operator)


Du hast der Klasse Ficus einen Konstruktor gegeben, der einen float-Parameter erwartet und damit implizit den Default-Konstruktor entfernt.

In C++ gilt die Regel, dass jeder Konstruktor einer abgeleiteten Klasse (hier LuxusFicus) einen Konstruktor der Basisklasse (Ficus) aufruft, und zwar entweder den, der explizit angegeben wird (siehe unten) oder, falls keiner angegeben wird, den Default-Konstruktor. Diesen hast du aber bei Ficus aufgehoben.

Um den Fehler abzustellen, musst du nun:
* entweder einen (parameterlosen) Default-Konstruktor Ficus::Ficus() schreiben. Dieser wird dann vom Default-Konstruktor LuxusFicus::LuxusFicus() verwendet. Vorsicht: Dadurch entstehen Pflanze-Instanzen, deren Member (groesse, maxgroesse, giftig) nicht initialisiert sind und daher Zufallswerte enthalten.
* oder einen Konstruktor LuxusFicus::LuxusFicus(float g) schreiben, der den g-Parameter an Ficus::Ficus(float g) weitergibt, nämlich so:

C++:
class LuxusFicus : public Ficus{
public:
    LuxusFicus () : Ficus (1.80) {} // Default-Konstruktor initialisiert Ficus auf 1,80 m
};



Das beruhigt zwar den Compiler, ist aber wahrscheinlich nicht besonders sinnvoll.

Du hast weiter oben einen Designfehler gemacht: Die Basisklasse (Zimmerpflanze) hat keinen Init-Code für die eigenen Member, d.h. sie verlässt sich drauf, dass die Ableitungen sie richtig initialisieren werden. Daran musst du bei jeder weiteren Zimmerpflanze-Ableitung denken.

Über sowas wirst du garantiert früher oder später stolpern. Spätestens dann, wenn dein Projekt so groß geworden ist, dass du nicht mehr jede Kleinigkeit im Kopf haben kannst oder gar einen Mitarbeiter einstellst (ja ich weiß, du spielst nur herum, aber das sind die Dinge, die ein gutes Design ausmachen: Dass man den Klassen ansieht, wie sie zu benutzen sind).

Empfehlung: Gib der Zimmerpflanze einen Konstruktor, der bei der Ableitung die Angabe der benötigten Daten verlangt:

C++:
#include <iostream>

using namespace std;

class Zimmerpflanze{
    
protected:

    float groesse;
    int maxgroesse;
    bool giftig;
        
public:
    
    //    Dieser Konstruktor verlangt die wichtigen drei Parameter.
    //    Gleichzeitig wird der Default-Konstruktor entfernt, d.h.
    //    eine Ableitung mit Zimmerpflanze::Zimmerpflanze() ist
    //    nicht mehr möglich.
    Zimmerpflanze (float groesse_, int maxgroesse_, bool giftig_)
    : groesse (groesse_)
    , maxgroesse (maxgroesse_)
    , giftig (giftig_)
    {
    }  
};

class Ficus : public Zimmerpflanze{

public:
    Ficus(float g)
    : Zimmerpflanze (g, 300, false)    //    Hier wird die Zimmerpflanze initialisiert.
    {
    }
    
    float PreisBerechnen(){
       return (5+10*groesse);
    }
};

class LuxusFicus : public Ficus{
public:
    LuxusFicus (float groesse_) : Ficus (groesse_) {}
};

int main()
{
    Ficus F1(1.20);
    F1.PreisBerechnen();
    LuxusFicus L1 (1.80);
    L1.PreisBerechnen();
    
    
    cout << "Ficus Preis : " << F1.PreisBerechnen() << endl;
    cout << "Luxus Preis : " << F1.PreisBerechnen() << endl;

    return 0;
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: