1 Klasse für zwei und mehr Klassen verfügbar machen
-
Guten Morgen,
habe da ein echt dummes Problem, was auch irgendwie in keinem Buch wirklich beschrieben ist.
Ich habe eine Klasse ( MySocket )ich habe zwei weitere Klassen
Klasse1
Klasse2so, ich möchte mit Klasse1 und Klasse2 auf MySocket zugreifen. Beide Klassen sollen auf die selben Werte zugreifen. D.h. Wenn Klasse1 eine Variabel ändert soll diese auch in der Klasse2 den neuen Wert haben.
ich habe die Socketklasse schon erfolgreich in Klasse1 eingebunden.class Klasse1 public: MySocket ClientSocket; ...so damit kann ich wunderbar auf die Methoden und Variabeln der MySocket Klasse zugreifen, nur wie mach ich das jetzt noch aus der Klasse2 udn später noch aus 20 weiteren Klassen??
Hoffe ihr wisst was ich meine und könnt mir helfen.
-
Kannst du das statisch machen? Guck einfach mal, ob dir static hilft.
Ansonsten: Lass in deiner App-Klasse ein Objekt erstellen und alle anderen Klassen können mit AfxGetApp und entsprechendem Cast auf die Klasse zugreifen.
-
also mit static geht es nicht das hatte ich schonmal versucht.
ich hab das ganze schonmal hinbekommen nur das liegt 6 monate zurück...

hab das damals über den Kontruktor der einzelnen Klassen gemacht... und mit Pointern und dann die Objekte übergeben.
-
Das klingt doch auch gut - woran scheiterst du dieses Mal?

-
ich weiß nicht mehr wie ich es gemacht habe zudem sind meine c++ kenntnisse eingerottet
-
Gibt es eine Klasse die Klasse1 und Klasse2 kennt? Wo deren Instanzen erstellt werden?
Oder kennen die sich untereinander? Je nachdem musst du eine andere Lösung wählen.Mit der Syntax für den Konstruktor hast kein Problem, oder?

-
also ich mach das ganze mit der mfc...
klasse1 udn klasse2 sind beide von CDialog abgeleitet...
sprich für jede klasse auch eine dialogressource...
-
Von wo rufst du die dialoge auf? ist das die selbe klasse? sind die modal?
-
also kurze einleitung wie ich mein "projekt" aufbaue...
klasse1 ist die mainklasse, bzw auch der maindialog. Über diesen Dialog läuft alles.
In der OnInitDialog() Methode initialisiere ich mir eine Instanz meiner Socket Klasse, wodurch ein Socket angelegt wird und alles soweit vorbereitet wird das ich mich mit einem Server verbinden kann.Diese SocketKlasse ist von mir persönlich zusammengefriemelt, also ich nutze NICHT die von der MFC.
klasse2 und dessen dialog werden über die klasse1 aufgerufen!
void CServerManager_ClientDlg::OnVerbinden() { DVerbinden Dlg; Dlg.DoModal(); }so mit der klasse2 möchte ich nun die Verbindung zum Server ermöglichen. D.h. ich baue mir nen Button Verbinden auf den Dialog und wenn man darauf drückt wird halt eine Verbindung zum Server hergestellt über die Methode MySocket->SocketVerbinden(char *IP,int Port);
hoffe das erklärt udn hilft dir jetzt etwas mir zu helfen

-
ich mach das so:
in the App gibt es folgende variable:MySocket* m_pMySocket;(diesen musst du in der InitInstance mit NULL initialisieren!)
im kontruktor von der ersten klasse wird jetzt m_pMySocket die Adresse zugewiesen:CMySocket* m_pKlasse1Socket; theApp.m_pMySocket = m_pKlasse1Socket;jetzt kannst du immer darauf zugreifen.
im destruktor musst du den theApp-pointer wieder Null setzen.wenn du jetzt Klasse 2 aufmachst musst du im Konstruktor folgendes machen:
CMySocket m_pKlasse2Socket; if (theApp.m_pMySocket != NULL) m_pKlasse2Socket = theApp.m_pMySocket; else theApp.m_pMySocket = m_pKlasse2Socket;oder du greifst immer gleich auf den theApp-pointer zu, das macht das ganze ubersichtlicher/einfacher

Esco
-
Oder er erstellt ein normales Objekt und gibt die Referenz weiter.
Der Konstruktr sieht dann so aus:
DVerbinden::DVerbinden(MySocket& socket) : m_mySocket(socket) { //... was auch immer hier schon steht } Aufgerufen wird das dann so:void CServerManager_ClientDlg::OnVerbinden()
{
DVerbinden Dlg(ClientSocket);
Dlg.DoModal();
} [cpp]Viel einfacher wie ich finde...

-
hab das jetzt so gemacht nur dabei bejkomm ich diese Fehlermeldung:
D:\NEUER ORDNER\ServerManager_Client\DVerbinden.cpp(23) : error C2275: "CServerManager_ClientDlg" : Ungültige Verwendung dieses Typs als Ausdruck d:\neuer ordner\servermanager_client\servermanager_clientdlg.h(17) : Siehe Deklaration von 'CServerManager_ClientDlg'Hier meine Dateien bzw teile davon.
ServerManager_ClientDlg.h
class CServerManager_ClientDlg : public CDialog { // Konstruktion public: CServerManager_ClientDlg(CWnd* pParent = NULL); // Standard-Konstruktor MySocket *ClientSocket;Dies ist die Header der Klasse1. Dort lege ich die Instanz des MySocket Objektes an.
CServermanager_ClientDlg.cpp
BOOL CServerManager_ClientDlg::OnInitDialog() { CDialog::OnInitDialog(); ClientSocket = new MySocket;hier reserviere ich mir den Speicher.
DVerbinden.h
class DVerbinden : public CDialog { // Konstruktion public: DVerbinden(CWnd* pParent = NULL); // Standardkonstruktor MySocket *m_pClientSocket;heir lege ich mir einen Pointer an, an den ich später die Adresse der SocketInstanz übergeben kann, damit ich auf die Sockets zugreifen kann.
DVerbinden.cpp
DVerbinden::DVerbinden(CWnd* pParent) : CDialog(DVerbinden::IDD, pParent) { m_pClientSocket = &CServerManager_ClientDlg.ClientSocket; //{{AFX_DATA_INIT(DVerbinden) // HINWEIS: Der Klassen-Assistent fügt hier Elementinitialisierung ein //}}AFX_DATA_INIT }und das ist der Contruktor womit ich die Adresse des Sockets übergebe... nur leider klappt das nicht... hoffe ihr könnt mir nun weiter helfen.
hier reserviere ich mir den speicher
-
sorry ich raffs nicht ganz, aber ich denk es wuerd helfen, wenn du deine variablen anders bezeichnest, also pointer ohne fuehrendes C usw.
die einfachste Methode ist, wenn du einen theApp-pointer hast:
CMySocket *m_pClientSocketdiesen musst du dann einmal in der initinstance initialisieren, oder wegen mir sonstwo.
später greifst du dann von allen andern klassen ueber
theApp.m_pClientSocket->Aktion();darauf zu ohne weitere pointer auf dieses objekt zu erstellen.
Esco
-
@snoopdog: hast du meinen Post auch noch gelesen?
Diese Zeile hier ist völliger Murks:
m_pClientSocket = &CServerManager_ClientDlg.ClientSocket;Übergib das bitte als Parameter. Du darfst einen weiteren Parameter hinzufügen, trau dich.
@Esco: Zu deiner Version fällt mir irgendwie nur "Quick&Dirty" ein. Sowas ist eine Notlösung, wenn anderes zu kompliziert wird - und das hier ist eine einfache Initialisierung einer Membervariablen, wo bitte ist die Notwendigkeit, den Aufstand über die Applikation zu treiben?

Arbeitest du auch noch mit globalen Variablen und goto?
-
estartu_de schrieb:
@Esco: Zu deiner Version fällt mir irgendwie nur "Quick&Dirty" ein. Sowas ist eine Notlösung, wenn anderes zu kompliziert wird - und das hier ist eine einfache Initialisierung einer Membervariablen, wo bitte ist die Notwendigkeit, den Aufstand über die Applikation zu treiben?

Arbeitest du auch noch mit globalen Variablen und goto?
spricht ja nicht gerade fuer deinen programmierstil: "immer noch"...
ich habe im ganzen leben noch nie ein goto oder eine globale variable benutzt :D.
desweiteren ist ja die frage, wie du sie schon ein paar posts weiter oben geschrieben hast: "gibt es eine klasse, die beide anderen klassen kennt oä.?"ich kenne seine programmstruktur nicht, und kann nicht davon ausgehen, dasss ausser theApp, eine andere klasse beide klassen kennt. man muss den umweg ueber die applikation nicht gehen, es funktioniert mit jeder anderen klasse, die beide kennt genauso ;).
aber natuerlich ist dies hier ein forum, wo man beliebig seine polemik auspacken kann, auch wenns kein sinn macht.
Esco
-
@estartu... so bin jetzt wieder da,
hab das jetzt mal probiert mit dem 2. parameter, aber es gibt 4 fehlermeldungen,
d:\neuer ordner\servermanager_client\dverbinden.h(22) : error C2548: 'DVerbinden::DVerbinden' : Fehlender Standardparameter fuer Parameter 2 ServerManager_Client.cpp d:\neuer ordner\servermanager_client\dverbinden.h(22) : error C2548: 'DVerbinden::DVerbinden' : Fehlender Standardparameter fuer Parameter 2 ServerManager_ClientDlg.cpp d:\neuer ordner\servermanager_client\dverbinden.h(22) : error C2548: 'DVerbinden::DVerbinden' : Fehlender Standardparameter fuer Parameter 2 D:\NEUER ORDNER\ServerManager_Client\ServerManager_ClientDlg.cpp(181) : error C2660: 'DVerbinden::DVerbinden' : Funktion akzeptiert keine 1 Parameter Generieren von Code...void CServerManager_ClientDlg::OnVerbinden() { DVerbinden Dlg(ClientSocket); Dlg.DoModal(); }der Aufruf des Verbinden Dialogs
class DVerbinden : public CDialog { // Konstruktion public: DVerbinden(CWnd* pParent = NULL,MySocket& ClientSocket); // Standardkonstruktorheader datei Verbinden.h
DVerbinden::DVerbinden(CWnd* pParent,MySocket& ClientSocket) : CDialog(DVerbinden::IDD, pParent) { //{{AFX_DATA_INIT(DVerbinden) // HINWEIS: Der Klassen-Assistent fügt hier Elementinitialisierung ein //}}AFX_DATA_INIT }Konstruktor der Klasse Verbinden
hm irgendwie is das alles Käse..

-
Hallo,
es handelt sich um einen "C++-Grundlagen"-Fehler, wenn in einer Funktion ein default-Wert angegeben wird, dann müssen auch alle darauf folgenden Parameter einen default-Wert haben. Um also dein Problem zu lösen, drehst du einfach die Parameter um, und schon ist die genannte Regel erfüllt:
class DVerbinden : public CDialog { // Konstruktion public: DVerbinden(MySocket& ClientSocket, CWnd* pParent = NULL); // Standardkonstruktorund
DVerbinden::DVerbinden(MySocket& ClientSocket, CWnd* pParent) : CDialog(DVerbinden::IDD, pParent) { //{{AFX_DATA_INIT(DVerbinden) // HINWEIS: Der Klassen-Assistent fügt hier Elementinitialisierung ein //}}AFX_DATA_INIT }MfG