ERLEDIGT!!! Problem bei Datapool (Singeltonklasse)



  • scheint so als müßtest du den contructor private setzen damit du keine neue instanz erstellen kannst die änderungen hab ich mal gepostet 😉

    class Datapool{
        private:
        	...
        	Datapool(){} //erzeugt ein singleton?
        	...
            class klasseA{
    
    int main() {
    	Datapool::getInstance()->getKlasseA()->setName("aa");
        cout << Datapool::getInstance()->getKlasseA()->getName() << endl;
        Datapool::getInstance()->getKlasseA()->setName("bb");
        cout << Datapool::getInstance()->getKlasseA()->getName() << endl;
        Datapool::getInstance()->getKlasseA()->setName("cc");
        cout << Datapool::getInstance()->getKlasseA()->getName() << endl;
    
        Datapool::getKlasseA()->changeDatapoolName("lolo");
        cout << Datapool::getInstance()->getName() << endl;
        cout << Datapool::getKlasseA()->getName() << endl;
        return 0;
    }
    


  • zwutz schrieb:

    datapool.h

    class KlasseA;
    
    class Datapool
    {
    public:
      KlasseA* getKlasseA() const { return klasseA; }
      //...
    private:
      KlasseA* klasseA;
    };
    

    datapool.cpp

    #include "klasseA.h"
    
    Datapool::Datapool()
    : klasseA(new KlasseA())
    {
      //...
    }
    
    //...
    

    so in etwa, wenn ich dich richtig verstanden habe

    was ich noch erwähnen sollte,

    die Klassen sollten getrennt sein. Also jede Klasse in eine cpp und header
    Tu mir da bisschen schwer so zusammengeschriebene Klassen auseinander zu bauen.
    Die einzelne Klassen werden spöter halt relativ groß, deswegen würd ichs gern auseinandr haben.



  • loe schrieb:

    die Klassen sollten getrennt sein.

    in meinem Beispiel sind sie getrennt

    dein datapool hält lediglich einen Zeiger auf KlasseA, der im Konstruktor des Datapools initialisiert wird



  • könnte man nicht auch direct die klasse mit nem #include rein laden 😕

    class Datapool{
        private:
        	Datapool(){}
            string name;
    		#include "klasseA.h"
        public:
    ...
    


  • zwutz schrieb:

    loe schrieb:

    die Klassen sollten getrennt sein.

    in meinem Beispiel sind sie getrennt

    dein datapool hält lediglich einen Zeiger auf KlasseA, der im Konstruktor des Datapools initialisiert wird

    könntest du mir bitte Zeile 1+6 aus der Datapool.h erklären

    und Zeile 1 in der Datapool.cpp müsste heissen Datapool.h und nicht KlasseA.h oder? die KlasseA.h muss in der Datapool.h eingebunden werden oder hab ich da grad nen totalen denkfehler?



  • noobLolo schrieb:

    könnte man nicht auch direct die klasse mit nem #include rein laden 😕

    class Datapool{
        private:
        	Datapool(){}
            string name;
    		#include "klasseA.h"
        public:
    ...
    

    nee
    #include kannst auch nur über der Klasse



  • loe schrieb:

    nee
    #include kannst auch nur über der Klasse

    sicher? das macht doch der preprocessor dem ist das doch gleich wo das steht, der hat doch keinen syntax check 🤡 ?



  • loe schrieb:

    könntest du mir bitte Zeile 1+6 aus der Datapool.h erklären

    Zeile 1 ist eine Forward Declaration. Sie macht KlasseA in datapool.h bekannt, ohne dass du den Header einbinden musst. Den bindest du erst in datapool.cpp ein, was die Abhängigkeiten der Klassen etwas verringert.
    Zeile 6 ist nur eine Methode, mit der man von außen lesend auf das KlasseA-Objekt zugreifen kann. Soll man über die Methode auch schreiben können, musst du das const weglassen

    loe schrieb:

    und Zeile 1 in der Datapool.cpp müsste heissen Datapool.h und nicht KlasseA.h oder? die KlasseA.h muss in der Datapool.h eingebunden werden oder hab ich da grad nen totalen denkfehler?

    datapool.h musst du natürlich auch einbinden. Ich habs nur weggelassen, da du es eh schon drinstehen hast.
    klasseA.h musst du aber einbinden, da du in der datapool.h ja lediglich eine Forward Declaration hast



  • Das scheint mir alles komplizierter zu sein als es eigentlich sein muss. Warum legst du alle Objekte dynamisch an bzw. arbeitest mit Zeigern wenn Referenzen genausogut funktionieren?
    Nächste Frage: Warum hat Klasse A eine Methode, die ein Element von DataPool ändert?

    Du brauchst im Header der KlasseA DataPool.h nicht zu inkludieren, da im Header keinerlei Informationen über DataPool bekannt sein müssen, weder Klassenlayout noch Methodensignaturen. Verschieb´ die Zeile in KlasseA.cpp.
    Vereinfacht kann das dann so aussehen:

    #ifndef KlasseAH
    #define KlasseAH
    
    #include <string>
    
    class KlasseA
    {
    public:
       void change_datapool_name( const std::string& Name );
    };
    #endif
    
    #include "KlasseA.h"
    #include "DataPool.h"
    
    using namespace std;
    
    /* Warum der Umweg über KlasseA? */
    void KlasseA::change_datapool_name( const string& Name )
    {
       DataPool::instance().set_name( Name );
    }
    
    #ifndef DataPoolH
    #define DataPoolH
    
    #include "string>
    
    #include "KlasseA.h"
    
    class DataPool
    {
       std::string Name_;
       KlasseA KlasseA_;
    
    public:
       DataPool& instance();
    
       KlasseA& KlasseA();
    
       std::string name() const;
       void set_name( const std::string& Name );
    
    private:
       DataPool();
       DataPool( const DataPool& );
       DataPool& operator=( const DataPool& );
    };
    #endif
    
    #include "DataPool.h"
    
    using namespace std;
    
    DataPool::DataPool()
    {
    }
    
    DataPool& DataPool::instance()
    {
       static DataPool theDataPool;
       return theDataPool;
    }
    
    KlasseA& DataPool::KlasseA()
    {
       return KlasseA_;
    }
    
    string DataPool::name() const
    {
       return Name_;
    }
    
    void DataPool::set_name( const string& Name )
    {
       Name_ = Name;
    }
    


  • Vielen Dank für eure Hilfen
    habs aber nun doch über Pointer gelöst und zwar so:

    /*  * Datapool.h * */
    #ifndef DATAPOOL_H_
    #define DATAPOOL_H_
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    #include <string.h>
    
    #include "KlasseA.h"
    
    using namespace std;
    
    class Datapool{
    
    	private:
    		static Datapool* datapool;
    		KlasseA* meinPointer;
    
    	protected:
    		string name;
    		Datapool();
    
    	public:
    		static Datapool* getDatapool();
    		void setName(string n);
    		string getName();
    		KlasseA* getKlasseA();
    		void setKlasseA(KlasseA* pointer);
    };
    
    #endif /* DATAPOOL_H_ */
    
    // Datapool.cpp
    #include "Datapool.h"
    
    Datapool* Datapool::datapool = 0;
    
    Datapool::Datapool(){
    	name="";
    	meinPointer= NULL;
    }
    
    Datapool* Datapool::getDatapool(){
    	if (datapool == 0) {
    		datapool = new Datapool;
    	}
    	return datapool;
    }
    
    void Datapool::setName(string n){
    	name = n;
    }
    
    string Datapool::getName(){
    	return name;
    }
    
    KlasseA* Datapool::getKlasseA(){
    	if (meinPointer == NULL) {
    		meinPointer = new KlasseA();
    	}
    	return meinPointer;
    }
    
    void Datapool::setKlasseA(KlasseA* pointer){
    	meinPointer = pointer;
    }
    
    /*  * KlasseA.h *  */
    
    #ifndef KLASSEA_H_
    #define KLASSEA_H_
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    #include <string.h>
    
    using namespace std;
    
    class KlasseA{
    
    	public:
    		KlasseA();
    		void changeDatapoolName(string n);
    };
    
    #endif /* KLASSEA_H_ */
    
    //KlasseA.cpp
    #include "KlasseA.h"
    #include "Datapool.h"
    
    KlasseA::KlasseA(){
    }
    
    void KlasseA::changeDatapoolName(string n){
    	Datapool::getDatapool()->setName(n);
    }
    
    //main.cpp
    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    #include <string>
    #include "Datapool.h"
    
    using namespace std;
    
    int main(int argc, char *argv[]) {
      cout << "Singelton" << endl;
      Datapool::getDatapool()->setName("test1");
      cout << Datapool::getDatapool()->getName() << endl;
      Datapool::getDatapool()->getKlasseA()->changeDatapoolName("geaendert über KlasseA");
      cout << Datapool::getDatapool()->getName() << endl;
      return   0 ;
    }
    

Anmelden zum Antworten