Variable einer Klasse in einer anderen Klasse auswerten
-
Hi,
ich habe 2 Klasse:
Meine selbst erzeugte: HangmanWords
und die von der MFC erzeugte CHangmandlgEigenme Klasse
class HangmanWords { public: CString ChosenWord; HangmanWords(); virtual ~HangmanWords(); private: long zufall; void GetWord(); CString Word[20]; };
mit
void HangmanWords::GetWord() { Word[0] = "Taschenrechner"; Word[1] = "Schulbibliothek"; Word[2] = "Maultasche"; Word[3] = "Neunmalklug"; Word[4] = "Programmierkenntnisse"; Word[5] = "Eintagsfliege"; srand(5); zufall = rand(); ChosenWord = Word[zufall]; }
Wie kann ich den public-Wert ChosenWord jetzt in der vom MFC-Klassenassistenten erzeugten Klasse CHangmanDlg ChosenWord anwenden,
so dass ich zum beispiel diese variable einem Textfeld zuweisez.B.
m_strStaticChosenWord = ChosenWord;ich habs so probiert:
m_strStaticChosenWord = HangmanWords::ChosenWord;gibt jedoch Fehlermeldungen
Hab bereits Stundenlang das cppTutorial durchsucht aber nichts geeignetes gefunden.
Bitte um Hilfe
Danke
Gruß mercer
-
mercer schrieb:
Wie kann ich den public-Wert ChosenWord jetzt in der vom MFC-Klassenassistenten erzeugten Klasse CHangmanDlg ChosenWord anwenden,
so dass ich zum beispiel diese variable einem Textfeld zuweisez.B.
m_strStaticChosenWord = ChosenWord;ich habs so probiert:
m_strStaticChosenWord = HangmanWords::ChosenWord;gibt jedoch Fehlermeldungen
Uuuuhh, da haperts aber mächtig an den Grundlagen!
Schaun wir uns das mal genauer an:
m_strStaticChosenWord = HangmanWords::ChosenWord;
1. HangmanWords ist der Name deiner Klasse, du musst von dieser Klasse erst ein Objekt (Instanz) erzeugen, damit du überhaupt damit arbeiten kannst. Die Klasse ist nur der "Bauplan", aber nichts konkretes. Also musst du erst mal so was in der Art in deinen Code einfügen:
HangmanWords meineHangmanWorte; //meineHangmanWorte ist nun dein Objekt
2. Um auf (public-)Variablen eines Objekts zuzugreifen, musst du den Punkt-Operator verwenden, nicht den :: hier. Deine Zeile muss also richtig lauten:
m_strStaticChosenWord = meineHangmanWorte.ChosenWord;
Das ist zwar auch nicht optimal, es gäbe schönere Lösungen (get-Methoden und private-Variablen), aber erst einmal musst du das hier verstehen...
Außerdem würde ich dir raten deine Variablen-Namen etwas übersichtlicher und konsequenter zu wählen, wenn du schon m_strStaticChosenWord schreibst, sollte die Variable deiner Klasse statt ChosenWord vielleicht m_strChosenWord heißen. Das ist aber eigentlich Geschmackssache...Gruß Brainiac
-
Hm, Ok,
irgendwie wills nicht??Ich hab meine eigene Klasse HangmanWords mit der Methode GetWords() und der öffentlichen Membervariablen ChosenWord (siehe oben)
Jetzt dacht ich nach dem tollen Hinweis von Brainiac (danke dafür
),
dass ich jetzt ein Objekt in der MFC - Klasse CHangmanDlg einschließe.Etwa so
class CHangmanDlg : public CDialog { [b]HangmanWords myWords;[/b] // Konstruktion public: CHangmanDlg(CWnd* pParent = NULL); // Standard-Konstruktor // Dialogfelddaten //{{AFX_DATA(CHangmanDlg) enum { IDD = IDD_HANGMAN_DIALOG }; CString m_strChosenWord; //}}AFX_DATA // Vom Klassenassistenten generierte Überladungen virtueller Funktionen //{{AFX_VIRTUAL(CHangmanDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV-Unterstützung //}}AFX_VIRTUAL // Implementierung protected: HICON m_hIcon; // Generierte Message-Map-Funktionen //{{AFX_MSG(CHangmanDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnEnd(); //}}AFX_MSG DECLARE_MESSAGE_MAP() };
Jetzt kommen einige Fehlermeldungen:
error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'myWords'
error C2501: 'HangmanWords' : Fehlende Speicherklasse oder Typbezeichner
error C2501: 'myWords' : Fehlende Speicherklasse oder Typbezeichnerwas hab ich jetzt schon wieder verbrochen??
Gruß
mercer
-
Hat sich erledigt,
hab vergessen die Klasse HangmanWords zu includieren.Aber wenn euch was auffällt oder ihr noch Vorschläge habt, immer her damit
Gruß
mercer
-
Nochmal ich:
So siehts bisher aus:
MFC - Klasse
class CHangmanDlg : public CDialog { HangmanWords myWords; // Konstruktion public: CHangmanDlg(CWnd* pParent = NULL); // Standard-Konstruktor // Dialogfelddaten //{{AFX_DATA(CHangmanDlg) ...
Im OnInitDialog steht:
// ZU ERLEDIGEN: Hier zusätzliche Initialisierung einfügen MessageBox (myWords.ChosenWord);
Meine eigene Klasse
class HangmanWords { public: CString ChosenWord; HangmanWords(); virtual ~HangmanWords(); private: long zufall; void GetWord(); CString Word[20]; };
mit der Methode
void HangmanWords::GetWord() { Word[0] = "Taschenrechner"; Word[1] = "Schulbibliothek"; Word[2] = "Maultasche"; Word[3] = "Neunmalklug"; Word[4] = "Programmierkenntnisse"; Word[5] = "Eintagsfliege"; srand(5); zufall = rand(); ChosenWord = Word[zufall]; }
nur wie bring ich das ganze jetzt zum laufen??
Ist zwar fehlerlos aber es passiert nix
Muss ich da jetzt extra nen main Programm schreiben??Ich vermut mal, dass die Klasse HangmanWords gar nicht durchlaufen wird.
Kann man das iergendwie hinbekommen ohne main??
Sonst würde mein main sehr schnell sehr groß werden??Gruß
omly a noop mercer
-
Moin,
als aller erstes solltest Du Dir mal Grundkenntnisse über VC6 mit MFC(ich geh davon aus das Du das Benutzt) aneignen.
1. Es gibt keine main Funktion, wenn dann nur eine winmain. Allerdings erstellt die das Studio für Dich.
2. Die Funktion OnInitDialog wird schon durchlaufen bevor Dein Fenster erstellt wird. Schreibe statt (myWords.ChosenWord) einfach mal "Test" rein und starte Deine Anwendung, dann verstehst Du´s vielleicht was ich meine.
(Das Fenster wird erst in OnPaint erstellt.)3. Solltest Du dann irgendwann so weit sein, dass Du Deine Variable einem Textfeld oder etwas ähnlichem zugewiesen hast, muß danach ein UpdateData(FALSE) erfolgen, sonst wird Dein Dialogfeld nicht aktualisiert.
Gruß Sven
-
Außerdem mußt du irgendwo auch die Funktion getWord() (wieso ist die eigentlich private?) aufrufen, damit dein Zufallswort gefüllt werden kann.
PS: Mit dem "srand(5);" deaktivierst du quasi den Zufallsgenerator - der bekommt bei jedem Aufruf den selben Seed und erzeugt deshalb jedes Mal die selbe Zufallszahl. Es reicht völlig aus, srand() einmal im Programm aufzurufen - und dann am besten mit einem Wert, der sich bei jedem Start ändert (z.B. "time(0)").
PPS: Außerdem mußt du den Rückgabewert von rand() noch auf den Indexbereich deines Worte-Arrays runterskalieren - sonst erhältst du nur Datenmüll als Lösungswort.
-
Hallo,
danke für die Tipps.Ich hab jetzt mal nen bissl rumprobiert und habs zum laufen gebracht.
So siehts aus:
OnInitDialog der MFC-Klasse
// ZU ERLEDIGEN: Hier zusätzliche Initialisierung einfügen m_strChosenWord = myGetWords.GetWord(3); //Anstatt 3 hier dann die Zufallszahl UpdateData(FALSE);
eigene Klasse:
class HangmanWords { public: CString GetWord(int i); //CString ChosenWord; HangmanWords(); virtual ~HangmanWords(); private: //long zufall; CString Word[20]; };
und die Get - Methode
CString HangmanWords::GetWord(int i) { Word[0] = "Taschenrechner"; Word[1] = "Schulbibliothek"; Word[2] = "Maultasche"; Word[3] = "Neunmalklug"; Word[4] = "Programmierkenntnisse"; Word[5] = "Eintagsfliege"; return Word[i];
}
mein Problem ist jetzt, ich find hier entsteht ein richtiges Dureinander...Ich glaube nicht das dies im Sinne der OOP ist???
Eigentlich würde ich in der MFC-Klasse gerne nichts weiter tun außer Schnittstellen zu meiner Klasse zu erstellen und die Methoden, Variablen... der MFC-Klasse übergeben.
Mit meiner Lösung müsste ich aber den Code zur zufallsgenerierung direkt in die MFC-Klasse schreiben was mir irgendwie gar nicht gefällt.
Existiert da ne bessere Lösung??
Und wenn ja, könnt mir die mal jemand zeigen??
-
Habs geschafft, war keine große Sache mehr...
Hier mal die Übersicht
#include "HangmanWords.h" class CHangmanDlg : public CDialog { // HangmanWords myWords; HangmanWords myGetWords; // Konstruktion public: CHangmanDlg(CWnd* pParent = NULL); // Standard-Konstruktor // Dialogfelddaten //{{AFX_DATA(CHangmanDlg) enum { IDD = IDD_HANGMAN_DIALOG }; CString m_strChosenWord; //}}AFX_DATA // Vom Klassenassistenten generierte Überladungen virtueller Funktionen //{{AFX_VIRTUAL(CHangmanDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV-Unterstützung //}}AFX_VIRTUAL // Implementierung protected: HICON m_hIcon; // Generierte Message-Map-Funktionen //{{AFX_MSG(CHangmanDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnEnd(); //}}AFX_MSG DECLARE_MESSAGE_MAP() };
Im OnInitDialog:
// ZU ERLEDIGEN: Hier zusätzliche Initialisierung einfügen m_strChosenWord = myGetWords.GetWord(); UpdateData(FALSE);
class HangmanWords { public: CString GetWord(); //CString ChosenWord; HangmanWords(); virtual ~HangmanWords(); private: int irand( int a, int e); long zufall; CString Word[20]; };
CString HangmanWords::GetWord() { Word[0] = "Taschenrechner"; Word[1] = "Schulbibliothek"; Word[2] = "Maultasche"; Word[3] = "Neunmalklug"; Word[4] = "Programmierkenntnisse"; Word[5] = "Eintagsfliege"; zufall = irand(0,5); return Word[zufall]; } int HangmanWords::irand(int lowest, int highest) { //Aus nem Tutorial rauskopiert und angepasst srand((unsigned)time(0)); int random_integer; int range=(highest-lowest)+1; for(int index=0; index<20; index++) { random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0)); } return random_integer; }
wer mal lust und zeit hat, kann das ja mal überfliegen und prüfen ob das vom Stil her i.O. geht.
Wenn ich schon mit cpp anfange, wills ich ja gleich richtig lernen (die OOP).Nochmals danke an alle Antwortenden für die Tolle Hilfe
Gruß
mercer