Problem mit this und Konvertierungsoperator?



  • idefix schrieb:

    delete pZombie; //Wer löscht jetzt wenn? Habe ich noch nie ausprobiert
    

    Netter Weise wird niemand gelöscht, weil delete pZombie vor der Speicherfreigabe erst den Destruktor von Zombie aufruft, der über delete this den Destruktor von Zombie aufruft, der über delete this... ... ... Der Speicher wird dann erst freigegeben, nachdem das Programm auf irgendeine Weise wegen des Stack-Overflows beendet wird 🙂



  • Du hast doch die Problematik der Dreiecksbeziehung beschreiben. Wenn du eine Basisklasse von Player deklarierst, können die Klassen Karte, Zombie, Moorleiche über die Basisklassen Definition auf das eigentliche Player Objekt zugreiffen. Die Überlegung ist das die Klassendefinition bekannt ist, aber das Objekt ein anders. Unterscheidung zwischen Klasse und Objekt ist wichtig.

    Ich bezweifel das dieses Problem mit der Aufteilung in .cpp/.h erfolgreich sein wird. Da die Include-Reihenfolge das gleiche/ähnliche Problem haben würde. Forward Deklaration der Klasse Player finde ich eigentlich nicht so besonders gut. Ist wohl eher eine Geschmackssache.

    Was ist wenn es unterschiedliche Player Klassen gibt? Okay, das war nicht die Frage.

    Du musst das auch nicht mit einer abstakten Klasse machen. Eine gewöhliche Klasse ist völlig ausreichend.



  • idefix schrieb:

    Ich bezweifel das dieses Problem mit der Aufteilung in .cpp/.h erfolgreich sein wird. Da die Include-Reihenfolge das gleiche/ähnliche Problem haben würde. Forward Deklaration der Klasse Player finde ich eigentlich nicht so besonders gut. Ist wohl eher eine Geschmackssache.

    Es ging mir nicht um die Aufteilung .h/.cpp, sondern um die Verwendung einer Vorwärtsdeklaration allgemein (von mir aus auch komplett im Header, wobei die Implementierungen weiter unten stehen).
    Warum sind Vorwärtsdeklarationen "nicht so besonders gut"? Ich sehe nicht einmal einen Nachteil, den man je nach Geschmack verschieden stark werten könnte. Die Dreiecksbeziehung über Vorwärtsdeklarationen (mit welcher Dateiorganisation auch immer) aufzulösen ist IMHO viel direkter als eine Basisklasse hinzuzüfügen, die keine Abstraktion bietet, sondern nur der Vermeidung dieser Vorwärtsdeklaration dient (und dabei vernachlässigbaren tatsächlichen und einige Tipparbeit mit viel geistigem Overhead einführt).



  • So, so keine Geschmakssache!?

    1. Ich habe nicht gesagt das Vorwärtsdeklarationen nicht besonders gut sind, sondern nur das ich (persönlich) diese nicht besonders gut finde.

    2. Ich habe auch nicht von irgendwelchen Nachteilen geredet.

    3. Geistiger Overhead? Schick formuliert! Warum so aggressive? Das Denken ist frei und jeder hat seine Vorlieben.

    4. Das eine Vrowärtsdeklaration direkter ist? Warum? Man könnte genauso gut sagen, das eine Basisklasse allgemeiner ist.

    Ich möchte mich mit dir nicht streiten, was nun besser oder schlechter ist. Ich denke das jedes für sich seine Vor- und Nachteile bietet.



  • idefix schrieb:

    1. Ich habe nicht gesagt das Vorwärtsdeklarationen nicht besonders gut sind, sondern nur das ich (persönlich) diese nicht besonders gut finde.

    2. Ich habe auch nicht von irgendwelchen Nachteilen geredet.

    Ich habe mich nur ziemlich gewundert, wo bei einer Vorwärtsdeklaration der Haken ist, der dich stört. Wenn du schlicht ein schlechtes Gefühl dabei hast, na von mir aus :), denn...

    3. Geistiger Overhead? Schick formuliert! Warum so aggressive? Das Denken ist frei und jeder hat seine Vorlieben.

    ...so aggressiv klingen wollte ich nicht, sorry wenn ich das getan habe 🙂

    4. Das eine Vrowärtsdeklaration direkter ist? Warum? Man könnte genauso gut sagen, das eine Basisklasse allgemeiner ist.

    Ich fand die Deklaration direkter, weil der Code, den er mit einer Vorwärtsdeklaration schreiben würde, exakt derselbe wäre (vom Text und der sprachtechnischen Bedeutung her), den er schreiben würde, wenn sein Beispiel auch ohne ginge - nur, dass er ihn mit der Vorwärtsdeklaration an einer anderen Stelle schreiben müsste.
    Und dass eine Basisklasse allgemeiner ist, will ich gar nicht bezweifeln 🙂



  • Ich habe mich einmal nach alternativen zu Pointern umgeschautr und Smart Poiunter gefunden. Dann habe ich mir #Boost gezogen, kann damit aber noch nichts anfangen, weil die Dokumentation absolut unzureichend ist, keine Schnittstellen usw., kann mir da jemand helfen???



  • Inwiefern unzureichend? Unter "(Boost-Verzeichnis)\libs\smart_ptr\index.htm" gibt es die Interfaces, Dokumentation und ein paar kleine Beispiele für alle enthaltenen Smart-Ptr.



  • Ich finde es insofern nicht ausreichend, dass ich trotz dieser Dokumentation nicht im Stande bin die Smart Pointer richtig einzusetzen, geschweige denn sie überhaupt einzusetzten.Gruß
    Glamdring



  • Wüsstest du denn, wie dein Code ohne Smart-Ptr aussehen muss? (Wenn du gerade an einem konkreten Problem sitzt) Die Frage können einem Smart-Ptr nicht abnehmen 🙂



  • Nein, das ist ja mein Problem 😞

    Ich habs dennoch nochmal probiert, wenns richtig ist hab ich es versdtnaden, wenn nicht: buhuhuhu, naja:
    Spieler.h

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <ostream>  
    #include "all.h"
    using namespace std;
    
    	class Player;
    
    	namespace enums
    	{
    		enum type{Spell, Creature, Place};
    		enum mode{AM, VM};
    		enum kind{Untoter, Zombie}; //usw.
    	}
    
    	class Karte
    	{
    	public:
    		string name;
    		int cost;
    		enums::kind art;
    		enums::type typ;
    		Karte(){}
    		virtual ~Karte() = 0;
    	};
    
    	class Kreatur : public Karte
    	{
    	public:
    		int A, V, LB, MLB; 
    		int modus; //1 = AM, 2 = VM
    		bool attack(Kreatur* opponent)
    		{
    			opponent->LB -= A - opponent->V;
    			return(true);
    		}
    
    		bool change_mode()
    		{
    			switch(modus)
    			{
    				case 1:
    				{
    					modus = 2;
    					break;
    				}
    				case 2:
    				{
    					modus = 1;
    					break;
    				}
    			}
    			return(true);
    		}
    
    		Kreatur(){}
    		virtual ~Kreatur() = 0;
    	};
    
    	class Zombie : public Kreatur
    	{
    	public:
    		Zombie()
    		{
    			//art = Zombie;
    			name = "Zombie";
    			cost = 4;
    			//typ = enums::type[1];
    			A = 1000;
    			V = 600;
    			LB = 600;
    			MLB = 600;
    		}
    
    		~Zombie(){}
    		void Fluch(Kreatur* target){}
    	};	
    
    	class Moorleiche : public Kreatur
    	{
    	public:
    		Moorleiche()
    		{
    			//art = Untoter;
    			name = "Moorleiche";
    			cost = 4;
    			//typ = enums::type[1];
    			A = 1800;
    			V = 1000;
    			LB = 1400;
    			MLB = 1400;
    		}
    
    		~Moorleiche(){}
    
    		void Todeshauch(Kreatur* target)
    		{
    			A+=200;
    			if(attack(target))
    			{
    				A-=200;
    			}
    		}
    	};	
    
    	class Player
    	{
    	public:
    		smart_ptr<Karte> Deck[60];
    		smart_ptr<Karte> Friedhof[60];
    		smart_ptr<Karte> ingame[60];
    		int Kreaturen;
    		int HP, AP;
    		bool fill_deck(string nDeck);
    		bool Spell(Karte* Card);
    		bool Creature(Kreatur* Card);
    		Player(string nDeck);
    		~Player();
    	};
    
    	bool Player::fill_deck(string nDeck)
    	{
    		cout << "Im Deck sind folgende Karten:" << endl;
    		ifstream in;
    		in.open(nDeck.c_str(), ios_base::in);
    		for(string s; getline(in, s);) 
    		{
    		if(s == "Zombie")
    		{
    			for (int i=0; i<60;i++)
    			{
    				if(Deck[i].ptr->cost)
    				{}
    				else
    				{
    					cout << "Zombie" << endl;
    					Deck[i].ptr = new Zombie();
    				}
    			}
    			//break;
    		}
    		else if(s == "Moorleiche")
    		{
    			for (int i=0; i<60;i++)
    			{
    				if(Deck[i].ptr->cost)
    				{}
    				else
    				{
    					cout << "Moorleiche" << endl;
    					Deck[i].ptr = new Zombie();
    				}
    			}
    			//break;	
    		}//Zeile 60
    		}
    		return(true);
    	}
    
    	Player::Player(string nDeck)
    	{
    		if(fill_deck(nDeck))
    		{
    			for(int i=0; i<60; ++i)
    			{
    				Deck[i].ptr = 0;
    				ingame[i].ptr = 0;
    				Friedhof[i].ptr = 0;
    			}
    			HP = 2000;
    			AP = 10;
    			Kreaturen = 0;
    		}
    		else
    		{
    		}
    	}
    
    	Player::~Player()
    	{
    		delete[] Deck;
    	}
    

    all.h

    //Pseudo SmartPointer:
    
    template<class T> class smart_ptr
    {
    public:
    	T* ptr;
    public:
    	void init(T* nptr)
    	{
    		ptr = nptr;
    	}
    	smart_ptr()
    	{
    		ptr = 0;
    	}
    	~smart_ptr()
    	{
    		delete ptr;
    	}
    };
    

    und dann kommt das hier:

    #include "Spieler.h"
    
    int main()
    {
    	Player Player1("C:/Programme/Jugiohspiel/Decks/Deckundead.txt");
    	return(0);
    }
    

    Gruß
    Glamdring



  • Sieht doch alles richtig aus, nur der Destruktor von player ist unnötig. Und boost::scoped_ptr<> macht dasselbe wie dein smart_ptr<>, nur dass man statt init() reset() nimmt und nicht auf eine öffentliche Elementvariable zugreift, sondern entweder mit * oder -> dereferenziert oder .get() aufruft.
    Was geht denn jetzt nicht?



  • operator void schrieb:

    Was geht denn jetzt nicht?

    sry aber, was meinst du?

    Gruß
    Glamdring



  • Hm, kompiliert alles problemlos und macht was es soll? Dann nehme ich die Frage zurück 😉



  • 🤡 🤡 Juchuu 🤡 🤡

    Vielen Dank für deine Hilfe! 🙂


Anmelden zum Antworten