Kopieren eines Objektes verhindern



  • Hier mal Ausschnitte aus meinem Programm:

    //Dealer.cpp:
    Dealer::Dealer(Deck deck)
    	: Spieler(deck)
    {
    }
    
    //Deck.cpp:
    #include "Karten.h"
    #include "Deck.h"
    
    using namespace std;
    
    Deck::Deck()
    {
    	//Initialisierung des Decks 
    	neuesDeck();
    	mischen();
    }
    
    void Deck::neuesDeck()
    {
    	for (int i = 1; i <= 13; ++i)
    	{
    		char c;
    		switch (i) {
    		case 1:  c = 'A'; break;
    		case 2:  c = '2'; break;
    		case 3:  c = '3'; break;
    		case 4:  c = '4'; break;
    		case 5:  c = '5'; break;
    		case 6:  c = '6'; break;
    		case 7:  c = '7'; break;
    		case 8:  c = '8'; break;
    		case 9:  c = '9'; break;
    		case 10:  c = 'Z'; break;
    		case 11:  c = 'B'; break;
    		case 12:  c = 'D'; break;
    		case 13:  c = 'K';
    		}
    		for (int n = 0; n <= 1; ++n)
    		{
    			m_deck.push_back(new Karten(c, n));
    		}
    	}
    }
    
    void Deck::mischen()
    {
    	std::random_shuffle(m_deck.begin(), m_deck.end());
    }
    
    Karten Deck::geben()
    {
    	for (unsigned int i = 0; i < m_deck.size(); ++i)
    	{
    		if (!m_deck[i]->getIstVergeben())
    		{
    			m_deck[i]->setVergeben(1);
    			return (*m_deck[i]);
    		}
    
    	}
    }
    
    //Spieler.cpp:
    #include "Deck.h"
    #include "Spieler.h"
    
    using namespace std;
    
    Spieler::Spieler(Deck& deck)
    {
    	m_imSpiel = true;
    	m_deck = deck;
    	m_hand.drin(deck.geben(), deck.geben());
    }
    
    void Spieler::setzen()
    {
    	m_imSpiel = 0;
    	stand = m_hand.getSummeWert();
    }
    
    void Spieler::weitereKarte()
    {
    	if (m_imSpiel) m_hand.neueKarte(m_deck.geben());
    	else cout << "Sie können keine weitere Karte ziehen!" << endl;
    }
    
    bool Spieler::verloren()
    {
    	if (m_hand.getSummeWert() > 21)
    	{
    		cout << "Ihre Hand ist groesser als 21." << endl;
    		cout << "Sie haben verloren!" << endl;
    		getchar();
    		getchar();
    		return true;
    	}
    	return false;
    }
    
    bool Spieler::gewonnen()
    {
    	return (m_hand.getSummeWert() == 21 && m_hand.getAnzKarten() == 2);
    }
    
    void Spieler::ausgabe1()
    {
    	cout << "Ihre Karten: \n";
    	m_hand.anzeigen();
    }
    
    int Spieler::getStand() const
    {
    	return stand;
    }
    
    //main:
    int main()
    {
    	srand((unsigned int)time(0));
    
    	bedienung();
    
    	Deck deck;
    	Spieler benutzer(deck);
    	Dealer casino(deck);
    	char x;
    	bool bbreak = 0;
    
    	benutzer.ausgabe1();
    	casino.ausgabe();
    

    Es handelt sich hier um ein kleines BlackJack Spiel.
    Nun wid das erstellte Deck (irgendwie werden drei Decks erstellt??) nict von den anderen Klassen übernommen sondern lediglich kopiert. Ich kriege es nicht hin, dass ein Deck erstellt wird und beide (Spieler und Dealer) auf ein und das selbe Deck zugreifen.

    Ich wäre wirklich Dankbar, wenn mir jemand erklären würde wie es an diesem Beispiel funktioniert.



  • Das hat dir Th69 doch schon erklärt https://www.c-plusplus.net/forum/p2518946#2518946



  • Du müsstest dein m_deck als Referenz in der Klasse Spieler deklarieren und über die Initialisierungsliste setzen.
    Dein Kasino macht sogar schon direkt im Konstruktor-Parameter eine Kopie, die du auch eliminieren müsstest.

    Allerdings: ich würde das nicht so tun. Es ist die Frage, warum der Spieler überhaupt ein "Deck" kennen/haben soll. Das tut er doch im Kasino auch nicht. Also: wenn der Spieler neue Karten bekommt, würde ich diese von außen reingeben und dem Spieler gar kein Member m_deck geben!

    Auch kommt mir dein void Deck::neuesDeck() sehr fragwürdig vor. Erstens das for+case, zweitens was tut die n=0,1 loop und drittens das new. Wo werden denn die Karten wieder gelöscht? Eine Karte ist jetzt im Kopf kein Riesenobjekt, für das man Freispeicher bräuchte...



  • Kleiner Tip... wenn du einen Thread so anfängst:

    xnightman schrieb:

    Hier mal Ausschnitte aus meinem Programm:

    führt das dazu dass sehr viele Leute den Browser-Tab gleich wieder zu machen.
    Beschreib erst was du für ein Problem hast, und dann zeig den Code.



  • Danke erstmal für die Antworten.

    Okay, das einzige was jetzt noch fehlt ist, den Member m_deck als Referenz oder Zeiger zu machen. Wie muss ich das tun? Und was bedeutet per Initialisierungsliste initialisieren?

    Nachdem die Fragen gestellt wurden, hier die Änderungen im Quelltext:

    //Deck.h:
    class Deck
    {
    private:
    	vector<Karten> m_deck;
    	Deck(const Deck&) {};            
    	Deck& operator=(Deck const&) {};
    
    //Dealer.h:
    class Dealer : public Spieler  //Der Dealer ist ein Spieler
    {
    public:
    
    	Dealer(Deck& deck);
    
    	void ausgabe();
    	void spiel(class Spieler& s);
    };
    
    //Dealer.cpp:
    Dealer::Dealer(Deck& deck)
    	: Spieler(deck)
    {
    }
    
    //Spieler.h:
    class Spieler
    {
    protected:
    	Deck m_deck;
    	Hand m_hand;
    	bool m_imSpiel;
    	int stand;
    
    public:
    	Spieler(Deck& deck);
    	void setzen();
    	void weitereKarte();
    	void ausgabe1();
    
    	int getStand() const;
    
    	bool verloren();
    	bool gewonnen();
    };
    
    //Spieler.cpp:
    Spieler::Spieler(Deck& deck)
    {
    	m_imSpiel = true;
    	m_deck = deck;
    	m_hand.drin(deck.geben(), deck.geben());
    }
    


  • //Spieler.h:
    class Spieler
    {
    protected:
        Deck& m_deck; // <- Member als Referenz
    
        // ... 
    };
    
    //Spieler.cpp:
    Spieler::Spieler(Deck& deck)
      : m_deck(deck), m_imSpiel(true) // <-- Initialisierungsliste
    {
        m_hand.drin(deck.geben(), deck.geben());
    }
    

    Ich muß 'wob' zustimmen, daß ein Spieler das Deck gar nicht kennen sollte. Besser ist, du erstellst eine Game-Klasse, welche dann das Deck sowie die Spieler kennt und dort dann die Interaktion durchgeführt wird.



  • Okay vielen Dank.
    Aber wie mache ich das dann mit der Klasse Deck, dort bekomme ich derzeit an zwei Stellen Fehler.

    [code="cpp"
    //Deck.h:
    ]class Deck
    {
    private:
    vector<Karten> m_deck;
    Deck(const Deck&) {}; //Hier wird das Kopieren verhindert
    Deck& operator=(Deck const&) {}; //Hier die Zuweisung verhindert

    public:
    Deck();

    void neuesDeck();
    void mischen();
    Karten geben();
    };[/code]

    Deck.cpp:
    Deck::Deck()
    {
    	//Initialisierung des Decks 
    	neuesDeck();
    	mischen();
    }
    
    void Deck::neuesDeck()
    
    {
    	for (int i = 1; i <= 13; ++i)
    	{
    		char c;
    		switch (i) {
    		case 1:  c = 'A'; break;
    		case 2:  c = '2'; break;
    		case 3:  c = '3'; break;
    		case 4:  c = '4'; break;
    		case 5:  c = '5'; break;
    		case 6:  c = '6'; break;
    		case 7:  c = '7'; break;
    		case 8:  c = '8'; break;
    		case 9:  c = '9'; break;
    		case 10:  c = 'Z'; break;
    		case 11:  c = 'B'; break;
    		case 12:  c = 'D'; break;
    		case 13:  c = 'K';
    		}
    		for (int n = 0; n <= 1; ++n)
    		{
    			m_deck.push_back(new Karten(c, n));
    		}
    	}
    }
    
    void Deck::mischen()
    {
    	std::random_shuffle(m_deck.begin(), m_deck.end());
    }
    
    Karten Deck::geben()
    {
    	for (unsigned int i = 0; i < m_deck.size(); ++i)
    	{
    		if (!m_deck[i]->getIstVergeben())
    		{
    			m_deck[i]->setVergeben(1);
    			return (*m_deck[i]);
    		}
    
    	}
    }
    

Log in to reply