C++ Variablen "verknüpfen" aus zwei Klassen.



  • Ach so, dann muss ich damit die vollständige Klasse initialisieren.
    Somit macht es eigentlich wenig Sinn die Waffen Objekte in der int main() zu deklarieren sondern in einer inkludierten .cpp Datei?

    Also aktuell sieht die Struktur ungefähr wie folgt aus (sind jetzt eben "dumme" Variablen):
    c_Player.hpp

    #pragma once
    #include <iostream>
    
    using namespace std;
    
    class Player {
    public:
    	string PlayerName;
    	int n_Health;
    	int n_Xp;
    	int n_Resistence; // 1-20
    	int n_Level;
    	Weapon WeaponName;
    	Player(string n, int h, int x, int r, int l, string w) {
    		PlayerName = n;
    		n_Health = h;
    		n_Xp = x;
    		n_Resistence = r;
    		n_Level = l;
    		WeaponName = w;
    	}
    };
    

    c_Weapon.hpp

    #pragma once
    #include <iostream>
    
    using namespace std;
    
    class Weapon {
    public:
    	string WeaponName;
    	int n_MinDmg;
    	int n_MaxDmg;
    	int n_CritDmg;
    	Weapon(string a, int x, int y, int z) {
    		WeaponName = a;
    		n_MinDmg = x;
    		n_MaxDmg = y;
    		n_CritDmg = z;
    	}
    };
    

    FunctionCollector.hpp

    #pragma once
    
    #include <iostream>
    
    using namespace std;
    
    // Text handling
    void PrintDots(int);  // Slow printout of '.'
    void WriteText(string);  // char by char printout for effect
    

    Functions.cpp

    #include "FunctionCollector.hpp"
    #include "c_Weapon.hpp"
    #include "c_Player.hpp"
    
    #include <chrono>
    #include <thread>
    
    using namespace std;
    using namespace std::this_thread;
    
    void PrintDots(int dots) {
    	int n_latency = 0;
    	for (int i = 0; i < dots; ++i) {
    		cout << ".";
    		sleep_for(std::chrono::milliseconds(n_latency));
    	}
    }
    
    void WriteText(string s_Text) {
    	int n_latency = 0;
    	for (int i = 0; i < s_Text.size(); i++) {
    		cout << s_Text[i];
    		sleep_for(std::chrono::milliseconds(n_latency));
    	}
    }
    

    MainGame.cpp

    // Public Librarys
    #include <iostream>
    #include <chrono>
    #include <thread>
    // Personal Headerfiles
    #include "FunctionCollector.hpp"
    #include "c_Weapon.hpp"
    #include "c_Player.hpp"
    
    using namespace std;
    
    
    int main() {
    	// Initialize all Weapon Types
    	// Name, minDmg, maxDmg, critDmg
    	Weapon stick("Basic Stick", 1, 2, 2);
    
    	// Initialize Player character
    	// PlayerName, Health, XP, Resistence, Level, Equiped Weapon
    	Player Player1("xxx", 100, 0, 1, 1, "stick");
    

    Das ist der aktuelle Stand von den "angefangenen Bausteinen".
    Aber dann muss ich die Initialisierung im Idealfall von Weapon stick[...] aus der MainGame.cpp Datei entfernen da es dann vermutlich von der Struktur keinen Sinn mehr macht und pack dass dann in die c_Player.hpp Datei?

    Ich hab zwar das Buch fast durch und man sieht evtl., dass ich die Basics ungefähr verstanden habe aber ich bin nicht gelernter Programmierer sondern auf der Systemseite zuhause, was man dem Code sicher ansieht. 🙃

    Deswegen noch Danke an alle, die hier die Geduld mit mir aufbringen.



  • Ich meine, daß du statt dem Waffennamen direkt das Waffenobjekt übergibst:

    Player(string n, int h, int x, int r, int l, Weapon w)
    {
      weapon = w;
    }
    

    Nun mußt du nur noch den Aufruf in der main-Funktion anpassen (dies überlasse ich dir als Aufgabe, damit du verstehst, wie man Objekte übergibt) - ist eigentlich nur eine kleine Änderung.

    Edit: Wie von @Swordfish schon angemerkt, beschäftige dich auch mit der Initialisierungsliste - dann kannst du sogar gleiche Namen für die Konstruktorparameter und die Membervariablen wählen.

    Wenn du verschiedene Waffenobjekte definieren möchtest, dann kannst du diese in einem statischen Array (oder einem std:.vector<>) halten, z.B.

    const Weapon weapons[] =
    {
      { "Basic Stick", 1, 2, 2 },
      { "Better Stick", 2, 3, 4 },
      // ...
    };
    

    Als weitere Lernaufgabe, könntest du diese Daten auch aus einer Textdatei lesen.

    PS: using namespace std; sollte man niemals in Headerdateien verwenden, denn dadurch ergeben sich Probleme bei größeren Projekten mit unterschiedlichen Namensbereichen (und daher gewöhne dich nicht erst daran).
    Entweder explizit std::string ausschreiben oder einzelne Namen per using std::string; etc. auflisten.
    Noch besser, für Fortgeschrittene, wenn man einen eigenen Namensbereich wählt (anstatt alles im globalen Bereich zu haben).



  • Ich habe das Gefühl ich verursache mehr Chaos in meinem Projekt als Ordnung 😂

    Ich habe das ganze etwas umgebaut, damit es etwas mehr dem "modernen" Standard entspricht was ich so gelesen habe.
    Jetzt sieht es wie folgt aus, funktioniert aber praktisch nichts mehr....
    MainGame.cpp

    // Public Librarys
    #include <iostream>
    // Personal Headerfiles
    #include "c_Weapon.hpp"
    #include "c_Player.hpp"
    
    using namespace std;
    
    int main() {
    	// Initialize all Weapon Types
    	Weapon stick("Basic Stick");
    
    	// Initialize Player character
    	Player Player1;
    
    	// Set Variables
    	string UserInput;
    	
    	cout << "Setze Spielername: ";
    	cin >> UserInput;
    	Player1.setPlayerName(UserInput);
    	cout << "Der Spielername ist: " << Player1.getPlayerName();
    
    	cout << "\n\n\n[ENTER]" << endl;
    	cin.get();
    }
    

    c_Player.hpp

    #pragma once
    #include <iostream>
    
    class Player {
    private:
    	std::string PlayerName;
    	Weapon EquipedWeapon;
    
    public:
    	Player(std::string Name);
    
    	void setPlayerName(std::string PlayerName);
    	void setPlayerWeapon(const Weapon& WeaponName);
    
    	void getPlayerName();
    	void getEquipedWeapon();
    };
    

    c_Player.cpp

    #include <iostream>
    #include "c_Player.hpp"
    #include "c_Weapon.hpp"
    
    using namespace std;
    
    // Methode
    void Player::setPlayerWeapon(const Weapon& WeaponName) {
    	this->EquipedWeapon = WeaponName;
    }
    
    void Player::setPlayerName(string Name) {
    	this->PlayerName = Name;
    }
    
    void Player::getPlayerName() {
    	cout << this->PlayerName;
    }
    
    void Player::getEquipedWeapon() {
    	cout << this->EquipedWeapon.WeaponName;
    }
    
    // Konstruktor
    Player::Player(string Name) {
    	this->PlayerName = Name;
    }
    

    c_Weapon.hpp

    #pragma once
    #include <iostream>
    
    class Weapon {
    public:
    	string WeaponName;
    	
    	Weapon(std::string Name);
    };
    

    c_Weapon.cpp

    #include <iostream>
    #include "c_Weapon.hpp"
    
    using namespace std;
    
    // Methoden
    
    // Konstruktor
    Weapon::Weapon(string Name) {
    	this->WeaponName = Name;
    }
    

    Ich weiss, dass bei Weapon der string immer noch als Publici st, wollte aber zuerst c_Player mit Getter und Setter einbauen.
    Nach Anleitung wie man mit Objekten in Objekten arbeitet müsste das rein theoretisch so ungefähr funktionieren nur funktioniert bei mir leider so gar nichts und woher es kommt versteh ich auch gerade nicht...



  • @100Lifes sagte in C++ Variablen "verknüpfen" aus zwei Klassen.:

    nur funktioniert bei mir leider so gar nichts und woher es kommt versteh ich auch gerade nicht

    Was heißt das? Kompilerfehler? Dann wäre es super, wenn du den hier mit angeben könntest. Macht das Programm was anderes, als erwartet? Dann sag doch, was es macht und was du stattdessen erwarten würdest.



  • Hier der Auszug von Visual Studio:

    Erstellen gestartet...
    1>------ Erstellen gestartet: Projekt: Console-Minigame-1, Konfiguration: Debug x64 ------
    1>c_Player.cpp
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Player.hpp(7,9): error C3646: "EquipedWeapon": Unbekannter Überschreibungsspezifizierer
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Player.hpp(7,22): error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Player.hpp(13,35): error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Player.hpp(13,35): error C2143: Syntaxfehler: Es fehlt "," vor "&"
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Weapon.hpp(6,9): error C3646: "WeaponName": Unbekannter Überschreibungsspezifizierer
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Weapon.hpp(6,19): error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Player.cpp(8,56): error C2511: "void Player::setPlayerWeapon(const Weapon &)": Überladene Memberfunktion nicht in "Player" gefunden
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Player.hpp(4): message : Siehe Deklaration von "Player"
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Player.cpp(9,2): error C2671: "Player::setPlayerWeapon": Statische Memberfunktionen haben keinen this-Zeiger
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Player.cpp(21,16): error C2039: "EquipedWeapon" ist kein Member von "Player".
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Player.hpp(4): message : Siehe Deklaration von "Player"
    1>c_Weapon.cpp
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Weapon.hpp(6,9): error C3646: "WeaponName": Unbekannter Überschreibungsspezifizierer
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Weapon.hpp(6,19): error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Weapon.cpp(10,8): error C2039: "WeaponName" ist kein Member von "Weapon".
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Weapon.hpp(4): message : Siehe Deklaration von "Weapon"
    1>Functions.cpp
    1>MainGame.cpp
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Weapon.hpp(6,9): error C3646: "WeaponName": Unbekannter Überschreibungsspezifizierer
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Weapon.hpp(6,19): error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
    1>C:\x\Console-Minigame-1\Console-Minigame-1\MainGame.cpp(31,9): error C2512: "Player": Kein geeigneter Standardkonstruktor verfügbar
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Player.hpp(4,7): message : Siehe Deklaration von "Player"
    1>C:\x\Console-Minigame-1\Console-Minigame-1\MainGame.cpp(39,60): error C2679: Binärer Operator "<<": Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operanden vom Typ "void" akzeptiert (oder keine geeignete Konvertierung möglich)
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(465,39): message : kann "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::basic_streambuf<char,std::char_traits<char>> *)" sein
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(440,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(const void *)"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(422,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(long double)"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(404,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(double)"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(386,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(float)"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(368,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(unsigned __int64)"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(350,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(__int64)"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(332,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(unsigned long)"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(314,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(long)"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(295,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(unsigned int)"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(269,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(int)"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(250,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(unsigned short)"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(216,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(short)"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(198,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(bool)"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(193,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::ios_base &(__cdecl *)(std::ios_base &))"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(188,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::basic_ios<char,std::char_traits<char>> &(__cdecl *)(std::basic_ios<char,std::char_traits<char>> &))"
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\ostream(183,39): message : oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::basic_ostream<char,std::char_traits<char>> &(__cdecl *)(std::basic_ostream<char,std::char_traits<char>> &))"
    1>C:\x\Console-Minigame-1\Console-Minigame-1\MainGame.cpp(39,60): message : bei Anpassung der Argumentliste "(std::basic_ostream<char,std::char_traits<char>>, void)"
    1>Code wird generiert...
    1>Die Erstellung des Projekts "Console-Minigame-1.vcxproj" ist abgeschlossen -- FEHLER.
    ========== Erstellen: 0 erfolgreich, 1 fehlerhaft, 0 aktuell, 0 übersprungen ==========
    
    


  • Du hast vergessen, c_Weapon.hpp in c_Player.hpp einzubinden:

    #include "c_Weapon.hpp"
    

    (sonst kennt der Compiler den Typ Weapon nicht).

    PS: Du solltest bei void setPlayerWeapon(const Weapon& WeaponName) den Parameter nur weapon nennen, da es ja kein Name ist, sondern ein Weapon-Objekt).
    Und noch ein wenig Englischnachhilfe: es heißt EquippedWeapon.



  • Manchmal fühl ich mich echt etwas beschränkt und bin sehr dankbar für eure Geduld mit mir.
    Englisch "Patzer" ausgebessert.
    Jetzt ist auch klar, wieso ich c_Weapon.hpp in die CPP Datei einbinden musste da ich es bei der c_Player.hpp verpeilt habe. Ist jetzt auch korrigiert.

    Jetzt erhalte ich aktuell noch folgende Meldung:

    1>c_Player.cpp
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Player.cpp(24,29): error C2512: "Weapon": Kein geeigneter Standardkonstruktor verfügbar
    1>C:\x\Console-Minigame-1\Console-Minigame-1\c_Weapon.hpp(4,7): message : Siehe Deklaration von "Weapon"
    

    Diese Meldung ist im Tutorial wo ich gefolgt bin leider nie aufgetreten und ich habe es (abgesehen von Variablenamen) extra nachgebaut.
    Ich kann es auch nicht 100% nachvollziehen da ich extra die Classes auf das Minimum, 1 Variable, reduziert habe.



  • Es existiert kein parameterloser Konstruktor für Weapon, so daß EquippedWeapon in der Klasse Player nicht standardmäßig erzeugt werden kann.
    Du müßtest entweder über die Initialisierungsliste eine Standard-Waffe setzen oder aber den parameterlosen Konstruktor Weapon() zu der Klasse hinzufügen (überlege dir mal logisch, was es bedeutet, wenn keine Waffe zugewiesen wurde).

    Außerdem benutzt du in main bei

    Player Player1;
    

    ebenso den parameterlosen Konstruktor, aber du hast diesen nicht definiert, sondern nur den mit einem Namen als Parameter.



  • @100Lifes sagte in C++ Variablen "verknüpfen" aus zwei Klassen.:

    class Weapon {
    public:
    string WeaponName;

    Weapon(std::string Name);
    };

    Nochwas anderes:

    Gewöhne dir an, 1-parametrige Konstruktoren standardmäßig als explicit zu deklarieren. Das vermeidet, dass der Konstruktor an bestimmten Stellen automatisch aufgerufen werden kann.

    (siehe https://en.cppreference.com/w/cpp/language/explicit und https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-explicit)



  • @wob Muss ich mir mal durchlesen.
    Danke für den Hinweis.

    @Th69 Alles klar. Also muss ich zunächst einen leeren Konstruktor machen und diesen dann überladen damit das Programm dann nicht in einen Fehler läuft in der c_Weapon.cpp Datei. Jetzt bin ich schonmal etwas schlauer.
    Jetzt hab ichs auch geschafft einmal das ganze zu speichern und abzurufen:

    // In der main Function
    	cout << "Setze Spielername: ";
    	cin >> UserInput;
    	Player1.setPlayerName(UserInput);
    	cout << "Der Spielername ist: ";
    	Player1.getPlayerName();
    

    Kleine Frage: Ich habe versucht void Player::getPlayerName() zu string Player::getPlayerName() umzustellen (in der c_Player.cpp und c_Player.hpp) um den Output in einer Variable zu speichern. Ohne Erfolg obwohl ich dann cout << this->PlayerName zu return this->PlayerName gemacht habe. Was hab ich da verpennt?

    ABER, ich habe jetzt ein ganzes Stück mehr verstanden und irgendwo immerhin ein Hauch von Fortschritt erzielt.

    	cout << "Du erhälst \"Stick\" als Waffe." << endl;
    	Player1.setPlayerWeapon(stick);
    	cout << "Deine aktuelle Waffe: ";
    	Player1.getEquippedWeapon();
    	
    	cout << "\n\n";
    		
    	Player1.setPlayerWeapon(BigStick);
    	cout << "Deine neue Waffe ist: ";
    	Player1.getEquippedWeapon();
    	cout << "\nMinimaler Schaden: ";
    	BigStick.getMinDmg();
    

    Das ganze funktioniert so wie ich mir das vorstelle und auch wenn es dumm klingt, bin ich etwas stolz.
    Ich habe noch den Konstruktor von Player und Weapon etwas umgebaut:
    Konstruktor Player

    Player::Player() {
    }
    
    Player::Player(string Name) 
    	: PlayerName(Name) {
    }
    

    Konstruktor Weapon

    // Konstruktor
    Weapon::Weapon() {
    }
    
    Weapon::Weapon(string Name, int minDmg) 
    	: WeaponName(Name), MinDmg(minDmg) {
    }
    

    Ich wäre vermutlich schon längst verzweifelt ohne eure Hilfe. 😅

    Dann eben aktuell noch die einzige offene Frage wäre, wie ich anstelle von einem cout das ganze als return value erhalten könnte.



  • Wenn du die Getter-Funktionen korrekt mit return implementiert hast, dann kannst du, wie vorher auf die Membervariable zugreifen:

    cout << Player1.getPlayerName();
    

    oder

    std::string name = Player1.getPlayerName();
    

    (die einzelne Anweisung Player1.getPlayerName(); führt zwar die Funktion aus, macht aber dann nichts mit dem Ergebnis - der Compiler sollte aber eine Warnung dafür ausgeben, denn mit Optimierungen würde der Compiler den ganzen Aufrufcode dafür eliminieren).



  • @100Lifes sagte in C++ Variablen "verknüpfen" aus zwei Klassen.:

    Kleine Frage: Ich habe versucht void Player::getPlayerName() zu string Player::getPlayerName() umzustellen (in der c_Player.cpp und c_Player.hpp) um den Output in einer Variable zu speichern. Ohne Erfolg obwohl ich dann cout << this->PlayerName zu return this->PlayerName gemacht habe. Was hab ich da verpennt?

    Das klingt generell erstmal richtig - das solltest du auch machen! Daher: keine Ahnung, was du da verpennt hast 🙂

    Ich habe noch den Konstruktor von Player und Weapon etwas umgebaut:

    Warum die Konstruktoren ohne Parameter? Soll es wirklich Spieler ohne festgelegte Namen geben oder Waffen, bei denen noch nichts festgelegt ist? Wenn du ein Weapon weapon; erzeugst, ist darin erstmal gar nichts festgelegt. Eventuell wäre es sinnvoll, einer solchen Waffe 0 min/max/crit Schaden zu geben - oder aber den Construktor ganz zu streichen.



  • Hab es nochmals probiert mit dem return... vielleicht hab ich vorher in den .hpp dateien verpennt std::string zu machen und hab nur string eingegeben zur funktions return value.

    @wob Ich habe den leeren Constructor weil sich gerade bei der Waffe herausgestellt hat, dass wenn ich ein Player eruzeuge und ohne leeren Constructor ran gehe ich mehr Fehlermeldungen erhalte als es Reis in China gibt gefühlt.
    Das ich eine "None" Waffe einfüge oder sowas wäre evtl. eine Idee um Bugs zu verhindern was durchaus ein valider Punkt ist.

    Aber ich bin gerade echt froh, dass ich heute endlich mal ein bisschen Fortschritt machen konnte.



  • Tja, aller Anfang ist schwer, aber ich habe den Eindruck, du bist auf einem guten Wege. Viel Erfolg weiterhin.



  • Vielen Dank für all die Hilfe @Th69 , @wob und allen anderen. ^^

    Eine kleine letzte Frage noch.
    Jetzt hab ich ja ein Userinput den ich zuerst in eine lokale variable abfange und dann der Funktion übergebe. Kann ich das eigentlich irgendwie auch in einer Zeile machen weil es lässig wäre?

    	cin >> UserInput;
    	Player1.setPlayerName(UserInput);
    


  • @100Lifes sagte in C++ Variablen "verknüpfen" aus zwei Klassen.:

    Vielen Dank für all die Hilfe @Th69 , @wob und allen anderen. ^^

    Eine kleine letzte Frage noch.
    Jetzt hab ich ja ein Userinput den ich zuerst in eine lokale variable abfange und dann der Funktion übergebe. Kann ich das eigentlich irgendwie auch in einer Zeile machen weil es lässig wäre?

    	cin >> UserInput;
    	Player1.setPlayerName(UserInput);
    

    Erstmal nein.

    Wichtigster Grund: das "setPlayerName()" soll nicht wissen müssen, woher der Namen kommt. Ob von der Tastatur eingelesen, aus einem Savegame eingelesen, aus einem Onlinedienst für zufällige Namen etc.

    Was du natürlich aber machen kann (die Antwort lautet also "Ja"): schreibe dir eine Funktion, die dir einen Usernamen einliest.

    Also im einfachsten Falle:

    std::string askForPlayername() {
        std::cout << "Bitte gib einen Spielernamen ein!\n";
        std::string username;
        std::cin >> username;  // vielleicht willst du auch mit getline arbeiten, um Leerzeichen im Namen zu erlauben
        return username;
    }
    
    [...]
    
    player1.setPlayerName(askForPlayername());


  • getline wäre noch ein guter input aber in dem Fall lohnt es sich wohl eher nicht dafür eine Funktion zu schreiben. Dann lassen wir das so und danke nochmals ^^



  • @100Lifes sagte in C++ Variablen "verknüpfen" aus zwei Klassen.:

    getline wäre noch ein guter input aber in dem Fall lohnt es sich wohl eher nicht dafür eine Funktion zu schreiben. Dann lassen wir das so und danke nochmals ^^

    Doch, das lohnt sich (fast) immer. Kleine Funktionen sind super!



  • @wob Ja gut, dann hab ich jetzt eine Funktion gemacht die evtl sogar etwas flexibler ist als zunächst angenommen....
    Nur kommt jetzt eine Frage und ich hab das Gefühl es ist was total logisches.

    Functions.cpp

    #include "FunctionCollector.hpp"
    void RequestPlayerName(bool InputType) {
    	// InputType = True -> UserInput
    	//			 = False -> SaveFile
    	if (InputType == true) {
    		string NewUserName;
    		cout << "Setze deinen Spierlnamen: ";
    		cin >> NewUserName;
    		Player1.setPlayerName(NewUserName);
    	} else {
    		cout << "Read from SaveFile not supported yet";
    	}
    }
    

    FunctionCollector.hpp

    #include <iostream>
    
    #include "c_Weapon.hpp"
    #include "c_Player.hpp"
    void RequestPlayerName(bool);
    

    MainGame.cpp

    #include "c_Weapon.hpp"
    #include "c_Player.hpp"
    #include "FunctionCollector.hpp"
    
    	RequestPlayerName(true);
    	cout << "Der Spielername ist: " << Player1.getPlayerName();
    

    Ich erhalte aus Functions.cpp die Meldung, dass Player1 ein "nichtdeklarierter Bezeichner" ist.
    Da ich aber in Functions.cpp die FunctionCollector.hpp Datei inkludiert habe und dort drin dann c_Player.hpp müsste das doch eigentlich funktionieren nicht?



  • RequestPlayerName ist eine freie Funktion und kennt den Spieler daher nicht:

    void RequestPlayerName(Player& Player1, bool InputType) {
    	// InputType = True -> UserInput
    	//	     = False -> SaveFile
    	if (InputType == true) {
            ...
            }
    }
    

    Die Signatur der (ohnehin falschen) Deklaration in der hpp müsste angepasst werden. InputType ist als Bezeichner allerdings auch ein wenig irreführend.
    Beachte auch if (InputType == true), if (InputType = true) ist eine Zuweisung (und die Bedingung ist immer erfüllt). Daher wird auch eigentlich immer das kürzere if (InputType) verwendet. Die umgekehrte Bedingung könnte man dann auch statt if (InputType == false) als if (!InputType) schreiben.
    Das ist ein wenig Gewöhnungssache, aber kürzerer Code ist in vielen Fällen auch schneller zu erfassen.