Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Problem mit Klassen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
27.06.2003, 16:03 Uhr
Dirk22



Hi,

ich habe zwei Klassen "Klasse1" und "Klasse2". "Klasse 2" ist eine public Ableitung von "Klasse1". In einer dritten Klasse "Hauptklasse" sind beide Klassen eingebunden.
Die Hauptklasse enthält unter public eine boolesche Variable.
Und auf den aktuellen Inhalt dieser booleschen Variable muss ich in Klasse1 und in Klasse2 in den Funktionen1 und Funktionen2 zugreifen können.
Im Hauptprogramm erstelle ich mir dann nur ein Objekt der Klasse "Hauptklasse".

Hauptklasse
-----------

#include "Klasse1.h"
#include "Klasse 2.h"

Nun erzeuge ich 2 Zeiger auf die Klassen.

Objekt1 = new Klasse1;
Objekt2 = new Klasse2;


Klasse1 - Funktion1
-------------------

If (boolesche Variable der Hauptklasse)
{ ...}


Klasse2 - Funktion2
-------------------

If (boolesche Variable der Hauptklasse)
{...}

Was muss ich in den Klassen1 und 2 genau tun, um auf die boolesche Variable, die sich in der Hauptklasse befindet zugreifen zu können?


Im Hauptprogramm passiert dann folgendes:

Hauptklasse Hauptobjekt;

Falls Fragen an dieser Fragestellung auftauchen, fragt einfach nach.
Ist mir wirklich sehr wichtig. Ich mache da schon seit 3 Stunden dran rum.

Vielen Dank im Voraus

Dirk
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
27.06.2003, 16:35 Uhr
virtual
Sexiest Bit alive
(Operator)


Solange die Methoden in Klasse1/2 nicht Hauptobjekt aus main kennen, geht da garnichts. Mit den vorhandenen Informationen kann ich nicht viel anfangen.

Wenn Deine Hauptklasse sowas ist wie ein Singleton (dh ein Ding, was es nur einmal gibt), wäre die Lösung etwa folgende:


C++:
class Hauptklasse
{
   static Hauptklasse* dasHauptObject;
public:

   bool Variable; // Normallerweise sollte man auch hier eine get funktion spendieren, aber was solls

   Hauptklasse()
   {
       // Übliche Singleton asserstions hier
       // ....
       dasHauptObject = this;
   }
  
   static Hauptklasse* get() { return dasHauptObject; }
};

class Klasse1
{
    void function1()
    {
        if (Hauptklasse::get()->Variable)
        {
           ...
        }
    }
};

int main()
{
     Hauptklasse bla;
      ....
}


Das macht allerdings nur sinn. wenn Hauptklasse Singleton sein soll. Ist mir aber aus der Fragestellung nicht klargeworden.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
27.06.2003, 17:02 Uhr
Dirk22



Nein, die Hauptklasse ist leider kein Singleton.
Was hältst du von folgender Idee:
Wenn ich beim Erzeugen von Klasse1 und Klasse2 einfach einen Zeiger auf die boolesche Variable übergebe.

Hauptklasse:

C++:
Objekt1 = new Klasse1(Zeiger auf boolesche Variable der Hauptklasse);
Objekt2 = new Klasse2(Zeiger auf boolesche Variable der Hauptklasse);



Ich müsste dann halt noch den Konstruktor in Klasse1 und Klasse2 ändern.

Ist das so eine Möglichkeit? Oder ist die Idee total daneben?

mfg

Dirk
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
27.06.2003, 17:05 Uhr
virtual
Sexiest Bit alive
(Operator)


In der Regel finde ich schon allein Public Attributes, also die bool Variablen in der Hauptklasse total daneben.
Ich würde in Der Hauptklasse also einfach einen entsprechende Get-Methode einbauen (wenn Dir performance wichtig ist, kann die ja inline sein) und dann eine Referenz zu dieser Hauptklasse an Klasse1/2 übergeben
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
27.06.2003, 17:15 Uhr
Dirk22



Sorry, ich verstehe es nicht ganz. Wie kann ich denn von den Klassen 1 und 2 dann auf diese Get-Methode zugreifen?
Kannst du mir bitte ein kleines Beispiel dazu machen?

Vielen Dank im Voraus

Dirk
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
27.06.2003, 17:21 Uhr
virtual
Sexiest Bit alive
(Operator)



C++:
class HauptKlasse
{
private:
   bool Variable;

public:
   bool getVariable() const { return Variable; }
};

class Klasse1
{
private:
   HauptKlasse& rHaupt;

public:
   Klasse1(HautpKlasse& hk) :rHout(hk) {};

   void funktion()
   {
       if (rHaupt.getVariable())
       {
       }
   }
};

int main()
{
    Hauptklasse hk;
    Klasse1 k1(hk);

    k1.funktion();
}


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
27.06.2003, 17:45 Uhr
Dirk22



Vielen Dank für deine schnelle Antwort. Das werde ich jetzt gleich mal ausprobieren. Ich nehme an, dass ich in Klasse2 genauso vorgehen muss wie in Klasse1. Und natürlich muss ich in Klasse1 und 2 noch den Header der Hauptklasse includieren.
In der main will ich übrigens nur die Hauptklasse nutzen. Die Funktionen der Klasse1 und Klasse2 sollen nur in der Hauptklasse aufgerufen werden können.

Also, ich probiers dann mal aus

Vielen Dank nochmal

Dirk
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
27.06.2003, 17:59 Uhr
ao

(Operator)


Zuerst mal ne Frage: Hab ich die Klassenbeziehungen so richtig verstanden?

C++:
class Klasse1
{
    void Funktion1() { Hauptklasse::m_bBool; }
};

class Klasse2 : public Klasse1
{
    void Funktion2() { Hauptklasse::m_bBool; }
};

class Hauptklasse
{
    Klasse1 m_K1;
    Klasse2 m_K2;

public:
    bool    m_bBool;
};

int main ()
{
    Hauptklasse HKl;
    return 0;
}


Das geht technisch nur dann, wenn in Klasse1 und Klasse2 eine Referenz (oder ein Pointer) auf die umgebende Hauptklasse bekannt ist, aber das haben die anderen ja schon geschrieben.

Auf den ersten Blick mutet das Ganze etwas seltsam an. Möglicherweise schlägst du dich nur mit den Konsequenzen eines falschen Designs herum, und dann wäre es besser, das Design zu ändern als irgendwelche internen Details herumzureichen.

Aber um das zu beurteilen müßten wir wissen, was du eigentlich modellieren willst. Also was sind Klasse1, Klasse2 und Hauptklasse in Wirklichkeit?

ao

Dieser Post wurde am 27.06.2003 um 18:02 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
27.06.2003, 18:45 Uhr
Dirk22



@ao: Ja, genau so habe ich es gemeint.

Klasse1 = CTcpSocket
Klasse2 = CTcpListenSocket
Hauptklasse = CSenden

TcpSocket.h

C++:
#if !defined(AFX_TCPSOCKET_H__79D77B93_9BD4_11D7_BFA5_00B0D02125BB__INCLUDED_)
#define AFX_TCPSOCKET_H__79D77B93_9BD4_11D7_BFA5_00B0D02125BB__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// TcpSocket.h : Header-Datei
//



/////////////////////////////////////////////////////////////////////////////
// Befehlsziel CTcpSocket

class CTcpSocket : public CAsyncSocket
{
// Attribute
public:

// Operationen
public:
    CTcpSocket();
    virtual ~CTcpSocket();

// Überschreibungen
public:
    // Vom Klassen-Assistenten generierte virtuelle Funktionsüberschreibungen
    //{{AFX_VIRTUAL(CTcpSocket)
    //}}AFX_VIRTUAL

    // Generierte Nachrichtenzuordnungsfunktionen
    //{{AFX_MSG(CTcpSocket)
        // HINWEIS - Der Klassen-Assistent fügt hier Member-Funktionen ein und entfernt diese.
    //}}AFX_MSG

// Implementierung
protected:
    virtual void OnClose(int nErrorCode);
    virtual void OnAccept(int nErrorCode);
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ fügt unmittelbar vor der vorhergehenden Zeile zusätzliche Deklarationen ein.

#endif // AFX_TCPSOCKET_H__79D77B93_9BD4_11D7_BFA5_00B0D02125BB__INCLUDED_



TcpSocket.cpp


C++:
// TcpSocket.cpp: Implementierungsdatei
//

#include "stdafx.h"
#include "Test.h"
#include "TcpSocket.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTcpSocket

CTcpSocket::CTcpSocket()
{
    
}

CTcpSocket::~CTcpSocket()
{
}


//Die folgenden Zeilen nicht bearbeiten. Sie werden vom Klassen-Assistenten benötigt.
#if 0
BEGIN_MESSAGE_MAP(CTcpSocket, CAsyncSocket)
    //{{AFX_MSG_MAP(CTcpSocket)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif    // 0

/////////////////////////////////////////////////////////////////////////////
// Member-Funktion CTcpSocket

void CTcpSocket::OnAccept(int nErrorCode)
{
  
}

void CTcpSocket::OnClose(int nErrorCode)
{
    // Are there some errors?
    if (nErrorCode == 0)
    {
    // If not, close the connection
    Close();
    }
}




TcpListenSocket.h

C++:
// TcpListenSocket.h: Schnittstelle für die Klasse CTcpListenSocket.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_TCPLISTENSOCKET_H__79D77B94_9BD4_11D7_BFA5_00B0D02125BB__INCLUDED_)
#define AFX_TCPLISTENSOCKET_H__79D77B94_9BD4_11D7_BFA5_00B0D02125BB__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "TcpSocket.h"

class CTcpListenSocket : public CTcpSocket  
{
public:
    void setConnectSocket(CTcpSocket* secondSocket);
    CTcpListenSocket();
    virtual ~CTcpListenSocket();

protected:
    virtual void OnAccept(int nErrorCode);
private:
    CTcpSocket* connectSocket;
};

#endif // !defined(AFX_TCPLISTENSOCKET_H__79D77B94_9BD4_11D7_BFA5_00B0D02125BB__INCLUDED_)



TcpListenSocket.cpp


C++:
// TcpListenSocket.cpp: Implementierung der Klasse CTcpListenSocket.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "TcpListenSocket.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////

CTcpListenSocket::CTcpListenSocket()
{

}

CTcpListenSocket::~CTcpListenSocket()
{

}

void CTcpListenSocket::setConnectSocket(CTcpSocket* secondSocket)
{
    connectSocket = secondSocket;
}


//Dieses Ereignis wird ausgelöst, wenn ein
//Client eine Verbindung anfordert
void CTcpListenSocket::OnAccept(int nErrorCode)
{
    if (nErrorCode == 0)  //wenn kein Fehler
    {
            //die Verbindungsanforderung vom Client wird akzeptiert
            Accept(*connectSocket);    
    }
}



Senden.h


C++:
// Senden.h: Schnittstelle für die Klasse CSenden.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SENDEN_H__79D77BA9_9BD4_11D7_BFA5_00B0D02125BB__INCLUDED_)
#define AFX_SENDEN_H__79D77BA9_9BD4_11D7_BFA5_00B0D02125BB__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "TcpSocket.h"
#include "TcpListenSocket.h"

class CSenden  
{
public:
    int getErrorCode();
    void send(char* pnmea_frame_gga, char* pnmea_frame_xdr);
    void close();
    void open();
    void Init(int port);
    CSenden();
    virtual ~CSenden();

private:
    int socketPort;
    CTcpListenSocket* m_listenSocket;
    CTcpSocket* m_connectSocket;
    void sendNmeaData(char* pnmea_frame);

};

#endif // !defined(AFX_SENDEN_H__79D77BA9_9BD4_11D7_BFA5_00B0D02125BB__INCLUDED_)




C++:
// Senden.cpp: Implementierung der Klasse CSenden.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Senden.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////

CSenden::CSenden()
{
    
}

CSenden::~CSenden()
{

}

//////////////////////////////////////////////////////////////////////
// eigene Methoden
//////////////////////////////////////////////////////////////////////

void CSenden::Init(int port)
{
    socketPort = port;
    m_connectSocket = new CTcpSocket;
    m_listenSocket = new CTcpListenSocket;
    m_listenSocket->setConnectSocket(m_connectSocket);
}


int CSenden::getErrorCode()
{
    return m_connectSocket->GetLastError();
}


void CSenden::open()
{
    m_listenSocket->Create(socketPort);  
    m_listenSocket->Listen();            
}


void CSenden::close()
{
    m_listenSocket->Close();
    m_connectSocket->Close();
    delete m_listenSocket;
    delete m_connectSocket;
}


void CSenden::send(char* pnmea_frame_gga, char* pnmea_frame_xdr)
{
    sendNmeaData(pnmea_frame_gga);
    sendNmeaData(pnmea_frame_xdr);
}


void CSenden::sendNmeaData(char* pnmea_frame)
{
    int len = 300;
    int sent;
    char NmeaMsg[300];

    strcpy(NmeaMsg, pnmea_frame);
    //Zu sendende Nachricht vorhanden
    if (NmeaMsg != "")
    {
        //Länge der Nachricht ermitteln
        len = strlen(NmeaMsg);
        //Nachricht senden
        sent = m_connectSocket->Send(LPCTSTR(NmeaMsg),len);
        //Konnte die Nachricht gesendet werden?
        if (sent == SOCKET_ERROR)
        {
        
        }
    }
}




Dies sind meine Klassen. Bisher ist es so, dass wenn eine Verbindung zwischen einem Client und dem Server(meine Anwendung) besteht und dann ein weiterer Client versucht sich ebenfalls mit meiner Anwendung zu connecten, dass dann meine Anwendung abstürzt.
Nun hatte ich die Idee dieses Problem mit Hilfe einer booleschen Variablen zu lösen. Das Problem ist nur, dass ich in der Klasse CSenden 2 Objekte erstelle (eins von CTcpSocket und eins von CTcpListenSocket). Und die Ereignisfunktion OnAccept(), die aufgerufen wird, wenn der Client eine Verbindungsanforderung stellt steht in der Klasse CTcpListenSocket. Und die Funktion, die aufgerufen wird, wenn der Client die Verbindung beendet, steht in TcpSocket. Und in OnAccept von TcpListenSocket wollte ich folgendes tun:

C++:
void CTcpListenSocket::OnAccept(int nErrorCode)
{
    if (nErrorCode == 0)  //wenn kein Fehler
    {
        if (boolesche Variable)
        {
            //tue nichts
        }
        else
        {
            //die Verbindungsanforderung vom Client wird akzeptiert
            Accept(*connectSocket);    
            boolesche Variable = true;
    }
}



Und in der Ereignisfunktion OnClose() der Klasse CTcpSocket wird diese dann auf false gesetzt.


C++:
void CTcpSocket::OnClose(int nErrorCode)
{
    // Are there some errors?
    if (nErrorCode == 0)
    {
    // If not, close the connection
    Close();
    boolesche Variable = false;
    }
}



Ganz am Anfang muss diese boolesche Variable ja noch mit false initialisiert werden.
Das Problem bei der ganzen Sache ist nun, dass ich es schaffen muss in beiden Funktionen, die ja unterschiedlichen Klassen angehören wirklich dieselbe Variable zu benutzen. Diese boolesche Variable soll mir immer anzeigen, wenn ein Client mit meinem Server verbunden ist und wann nicht.
Deshalb kam mir die Idee, diese boolesche Variable in der Klasse CSenden unterzubringen. Und die beiden Klassen darauf zugreifen zu lassen.

Ich bin mal gespannt, was ihr für ein neues Design vorschlagt. Eigentlich ist das Ganze ja ein allgemeines Problem. Aber es ist halt sehr viel MFC drin. Ich hoffe, dass das Posting dann hier noch richtig ist.

Vielen Dank für eure Hilfe im Voraus

Dirk

Dieser Post wurde am 27.06.2003 um 19:51 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
28.06.2003, 10:54 Uhr
Dirk22



Bitte helft mir, ich komme nicht weiter. Wenn ich in der Klasse CTcpSocket eine Membervariable vom Typ CSenden anlegen will, dann erkennt er sie nicht, obwohl ich Senden.h includiert habe.

mfg

Dirk
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: