Objekt an Klassenkonstruktor übergeben



  • Hallo zusammen!

    Ich hab folgendes Problem:

    Ich definiere eine Klasse "Schachbrett":

    class Schachbrett{
    [...]
    	  Schachbrett(int breite){
    [...]
    	  }
    };
    

    Dazu eine Klasse "Dame". Ich möchte jeder Dame genau ein Schachbrett zuordnen. ("Jede Dame steht auf einem Schachbrett"):

    class Dame{
    	  private:
    	  int Zeile, Spalte;
    	  Schachbrett Brett;
    
    	  public:
    	  Dame(int z, int s, Schachbrett b){Zeile=z;Spalte=s;Brett=b;}
    };
    

    Das Hauptprogramm dazu:

    int main(){
    	Schachbrett b(6);
    	Dame a(0,0,b);
    
    	return 0;
    }
    

    Beim Kompilieren kommt diese Fehlermeldung:

    In constructor `Dame::Dame(int, int, Schachbrett)':
    no. matching function for call to `Schachbrett::Schachbrett()' 
     note candidates are: Schachbrett::Schachbrett(const Schachbrett&) 
     note:                 Schachbrett::Schachbrett(int)
    

    Ich versteh die Fehlermeldung nicht so ganz. Bin relativ neu bei C++, davor war ich mit PHP und Java unterwegs...

    Also ich dachte, ich könnte meinem Damenkonstruktor einfach ein Objekt vom Typ Schachbrett übergeben. Das scheint nicht zu funktionieren. Wenn ich die Fehlermeldung richtig verstehe, möchte er im Damenkonstruktor ein neues Schachbrett-Objekt erschaffen. 😕



  • In der Schachbrettklasse hast du nur einen Konstruktor mit einem int als Parameter. Im Konstruktor von Dame wird aber zuerst versucht, ein standardkonstruiertes Objekt von Schachbrett zu erstellen. Um direkt eine Zuweisung vorzunehmen, benutze die Konstruktor-Initialisierungsliste (suche mal danach).

    Ausserdem ist dein Vorgehen fragwürdig, da jeder Dame ein Schachbrett zugeordnet sein soll, und dieses auch separat erstellt wird. Hier würde wohl eine Referenz (oder ein Zeiger, je nach benötigter Flexibilität) besser passen als eine Kopie.



  • Genau das möchte ich ja nicht - ich möchte nicht für jede Dame ein Schachbrett erstellen, sondern jeder Dame ein Schachbrett zuweisen. (Vielleicht drück ich mich blöd aus.)

    Wie funktioniert das mit Zeigern? Muss dann die Klasse "Dame" dann so aussehen?

    class Dame{
    	  private:
    	  int Zeile, Spalte;
    	  Schachbrett* Brett;
    
    	  public:
    	  Dame(int z, int s, Schachbrett* b){Zeile=z;Spalte=s;Brett=b;}
    };
    


  • Also das funnktioniert soweit...:

    #include <iostream>
    #include <math.h>
    #include <cmath>
    #include <iomanip>
    
    using namespace std;
    
    class Schachbrett{
    	  public:
    	  int n;
    	  int** Feld;
    	  Schachbrett(int breite){
    	      n=breite;
    		  int** Feld = new int* [n];
    		  for(int i=0;i<n;i++) Feld[i] = new int[n];
    	  }
    };
    
    class Dame{
    	  private:
    	  int Zeile, Spalte;
    	  Schachbrett* Brett;
    
    	  public:
    	  Dame(int z, int s, Schachbrett* b){Zeile=z;Spalte=s;Brett=b;}
    };
    
    int main(){
    	Schachbrett b(6);
    	Dame a(0,0,&b);
    
    	return 0;
    }
    

    Wie greife ich denn jetzt in der Klasse Dame auf das entsprechende Schachbrett zu?
    Brett.n konnte ich z.B. nicht ansprechen...



  • So derefenziere er den Zeiger!



  • Also mit

    Brett->n
    

    konnte ich darauf zugreifen. So ganz leuchtet mir die ganze Geschichte aber noch nicht ein. Warum funktioniert denn

    *Brett.n
    

    nicht?

    Vielen Dank für die Hilfe!



  • hurz schrieb:

    Also mit

    Brett->n
    

    konnte ich darauf zugreifen. So ganz leuchtet mir die ganze Geschichte aber noch nicht ein. Warum funktioniert denn

    *Brett.n
    

    nicht?

    Wenn müsste letzteres "(*Brett).n" heißen. mit "*Brett.n" geht er davon aus das du "Brett.n", nicht "Brett" dereferenzieren willst.



  • Achso. Ich glaub, dann hab ichs soweit verstanden.

    Super, vielen Dank für eure Hilfe! :xmas1:



  • Trotzdem würde ich dir die Konstruktor-Initialisierungsliste anraten.

    Wenn du das mit Referenzen machst (was zu empfehlen ist, wenn eine Dame während ihrer ganzen Lebensdauer auf das selbe Schachbrett verweist), kommst du gar nicht darum herum, eine Initialisierungsliste zu schreiben.

    class Dame
    {
        private:
            Schachbrett& Brett;  // Referenz auf ein Schachbrett
            int Zeile;
            int Spalte;
    
        public:
            // Treffendere Variablennamen als z, s wählen (wenn schon, Member so nennen)
            Dame(int NeueZeile, int NeueSpalte, Schachbrett& NeuesBrett);
    };
    
    Dame::Dame(int NeueZeile, int NeueSpalte, Schachbrett& NeuesBrett)
    : Zeile(NeueZeile)    // Nach dem Doppelpunkt steht die Konstruktor-Initialisierungsliste.
    , Spalte(NeueSpalte)  // Die Member werden durch die Werte in den Klammern initialisiert.
    , Brett(NeuesBrett)   // Die einzelnen Initialisierungen sind durch Kommas getrennt.
    {
        // Konstruktor-Rumpf ist nun leer
    }
    

Anmelden zum Antworten