<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Frage: Klassen richtig einbinden]]></title><description><![CDATA[<p>Guten Abend.</p>
<p>Ich arbeite derzeit an einem kleinen Programm, einem Server, für den ich zwei Klassen habe.</p>
<p>1.) MainFrame: Die eigentliche Fensterklasse</p>
<pre><code>#ifndef MAINFRAME_H
#define MAINFRAME_H
#include &quot;wxcrafter.h&quot;
#include &lt;wx/socket.h&gt;
#define MAX_CLIENTS 5

//------------------------------------------------------------
//------------------------------------------------------------
// Klasse: MainFrame
//------------------------------------------------------------
//------------------------------------------------------------

class MainFrame : public MainFrameBaseClass
{
    public:
    MainFrame(wxWindow* parent);
    virtual ~MainFrame();

	enum
	{
		SERVER_START,
		SERVER_ID,
		SOCKET_ID
	};

	public:
	void OnServerStart( wxCommandEvent&amp; WXUNUSED(event) );
	void OnServerEvent( wxSocketEvent&amp; WXUNUSED(event) );
	void OnSocketEvent( wxSocketEvent&amp; event );
	void OnClientConnect( wxSocketEvent&amp; event );

    protected:
	virtual void OnButton2_closeButtonClicked(wxCommandEvent&amp; event);
    virtual void OnButton1_startButtonClicked(wxCommandEvent&amp; event);

	wxSocketBase *m_ClientSockets[MAX_CLIENTS];
	wxSocketServer *m_pSocketServer;
	ClientThread *m_pClientThread;
	wxCriticalSection m_csClientThreadCS;

	friend class ClientThread;

	DECLARE_EVENT_TABLE();
};
#endif // MAINFRAME_H
</code></pre>
<pre><code>#include &quot;MainFrame.h&quot;
#include &lt;wx/msgdlg.h&gt;
#include &lt;wx/log.h&gt; 

//------------------------------------------------------------
//------------------------------------------------------------
// Klasse: MainFrame
//------------------------------------------------------------
//------------------------------------------------------------

MainFrame::MainFrame(wxWindow* parent)
    : MainFrameBaseClass(parent)
{
   m_pSocketServer = 0;

   for ( int i = 0; i &lt; MAX_CLIENTS; i++ )
   {
	   m_ClientSockets[i] = 0;
   }
}

MainFrame::~MainFrame()
{

}

void MainFrame::OnButton1_startButtonClicked( wxCommandEvent&amp; event )
{	
	OnServerStart( event );
}

void MainFrame::OnButton2_closeButtonClicked( wxCommandEvent&amp; event )
{
	Close( true );
}

BEGIN_EVENT_TABLE(MainFrame, wxFrame)
   EVT_BUTTON(SERVER_START, MainFrame::OnServerStart)
   EVT_SOCKET(SERVER_ID, MainFrame::OnServerEvent)
   EVT_SOCKET(SOCKET_ID, MainFrame::OnSocketEvent)
END_EVENT_TABLE()

void MainFrame::OnServerStart( wxCommandEvent&amp; WXUNUSED(event) )
{
	wxIPV4address addr;

	try
	{
		// Create the address
		addr.Hostname( m_textCtrl1_IP -&gt; GetValue() );
		addr.Service( m_textCtrl2_Port -&gt; GetValue() );

		// Create the socket
		m_pSocketServer = new wxSocketServer( addr );

		// Check if the server is listening
		if ( !m_pSocketServer -&gt; IsOk() )
		{
		   return;	
		}

		// Set up the event handler
		m_pSocketServer -&gt; SetEventHandler( *this, SERVER_ID );
		m_pSocketServer -&gt; SetNotify( wxSOCKET_CONNECTION_FLAG );
		m_pSocketServer -&gt; Notify( true );
	}
	catch (...)
	{

	}
}

void MainFrame::OnServerEvent( wxSocketEvent&amp; WXUNUSED(event) )
{	
	try
	{
		// Check the array if a free Socket is available
		for ( int i = 0; i &lt; MAX_CLIENTS; i++ )
		{
			if ( m_ClientSockets[i] == 0 )
			{
				m_ClientSockets[i] = new wxSocketBase();
			}

			if ( m_ClientSockets[i] -&gt; IsDisconnected() )
			{
			   // Accept the new conncetion and get the socket pointer
			   m_ClientSockets[i] = m_pSocketServer -&gt; Accept( true );

			   // Tell the new socket how and where to process its events
		       m_ClientSockets[i] -&gt; SetEventHandler( *this, SOCKET_ID );
		       m_ClientSockets[i] -&gt; SetNotify( wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG );
		       m_ClientSockets[i] -&gt; Notify( true );
			   break;	
			}
		}
	}
	catch (...)
	{

	}
}

void MainFrame::OnSocketEvent( wxSocketEvent&amp; event )
{	
	try
	{
	   m_pClientThread = new ClientThread( this );

	   if ( m_pClientThread -&gt; Run() != wxTHREAD_NO_ERROR )
	   {
		   wxLogError( &quot;Can't create the thread!&quot; );
		   delete m_pClientThread;
		   m_pClientThread = NULL;
	   }
	}
	catch (...)
	{

	}
}

void MainFrame::OnClientConnect( wxSocketEvent&amp; event )
{
	wxSocketBase *pSocket = 0;
	wxString IP;
	wxIPV4address addr;
	char buffer[50];

	try
	{
		// The socket that had the event
		pSocket = event.GetSocket();

		// Handle the socket events
		switch ( event.GetSocketEvent() )
		{
		   case wxSOCKET_INPUT: 
				m_pSocketServer -&gt; GetPeer( addr );
				IP = addr.Hostname();
				m_richTextCtrl_Client_List -&gt; AppendText( IP );
                buffer[0] = 'H';
				buffer[1] = 'i';
				buffer[2] = '\0';
				pSocket -&gt; Write( buffer, sizeof( buffer ) ); break;
		   case wxSOCKET_LOST: 
			    m_richTextCtrl_Client_List -&gt; Clear();
				pSocket -&gt; Destroy(); break;
		}
	}
	catch (...)
	{

	}	
}
</code></pre>
<p>2.) ClientThread: Eine Klasse für Threads zum bearbeiten von Client-Anfragen (Bei Threads bin ich aber noch am einlesen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> )</p>
<pre><code>#ifndef CLIENT_THREAD_H
#define CLIENT_THREAD_H
#include &lt;wx/thread.h&gt;

//------------------------------------------------------------
//------------------------------------------------------------
// Klasse: ClientThread
//------------------------------------------------------------
//------------------------------------------------------------

class ClientThread : public wxThread
{	
   public:
   ClientThread( MainFrame *pHandler );
   ~ClientThread();	

   protected:
   virtual wxThread::ExitCode Entry();
   MainFrame *m_pHandler;
};
#endif // CLIENT_THREAD_H
</code></pre>
<pre><code>#include &quot;ClientThread.h&quot;

//------------------------------------------------------------
//------------------------------------------------------------
// Klasse: ClientThread
//------------------------------------------------------------
//------------------------------------------------------------

ClientThread::ClientThread
( MainFrame *pHandler ) :
   m_pHandler( pHandler )
{

}

ClientThread::~ClientThread()
{
	wxCriticalSectionLocker enter( m_pHandler -&gt; m_csClientThreadCS );
   	m_pHandler -&gt; m_pClientThread = NULL;
}

wxThread::ExitCode ClientThread::Entry()
{	
	//m_pHandler -&gt; OnClientConnect()

	return 0;
}
</code></pre>
<p>Mein Problem ist jetzt wie folgt:<br />
Beide Klassen besitzen in der jeweiligen Header-Datei eine Membervariable vom jeweils anderen Typ.</p>
<p>MainFrame =&gt; ClientThread *m_pClientThread;<br />
ClientThread =&gt; MainFrame *m_pHandler;</p>
<p>Ich kann aber hier in diesem Fall ja nicht einfach die Header-Dateien includieren, da die &quot;ClientThread.h&quot; und die &quot;MainFrame.h&quot; bereits von den CPP-Dateien includiert werden. Die Include-Guards lassen das ja nicht zu.</p>
<p>Deshalb bekomme ich derzeit beim Übersetzen den Fehler:<br />
&quot;MainFrame.h:38:2: error: ClientThread does not name a type&quot;</p>
<p>Wie löse ich das am Besten? Es tut mir Leid, wenn ich mich dumm anstelle - Ich hoffe, ihr könnt mir helfen. PS: Mein erster Post im Forum ^^.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/335232/frage-klassen-richtig-einbinden</link><generator>RSS for Node</generator><lastBuildDate>Fri, 24 Apr 2026 21:02:06 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/335232.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 07 Nov 2015 19:25:39 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Frage: Klassen richtig einbinden on Sat, 07 Nov 2015 19:25:39 GMT]]></title><description><![CDATA[<p>Guten Abend.</p>
<p>Ich arbeite derzeit an einem kleinen Programm, einem Server, für den ich zwei Klassen habe.</p>
<p>1.) MainFrame: Die eigentliche Fensterklasse</p>
<pre><code>#ifndef MAINFRAME_H
#define MAINFRAME_H
#include &quot;wxcrafter.h&quot;
#include &lt;wx/socket.h&gt;
#define MAX_CLIENTS 5

//------------------------------------------------------------
//------------------------------------------------------------
// Klasse: MainFrame
//------------------------------------------------------------
//------------------------------------------------------------

class MainFrame : public MainFrameBaseClass
{
    public:
    MainFrame(wxWindow* parent);
    virtual ~MainFrame();

	enum
	{
		SERVER_START,
		SERVER_ID,
		SOCKET_ID
	};

	public:
	void OnServerStart( wxCommandEvent&amp; WXUNUSED(event) );
	void OnServerEvent( wxSocketEvent&amp; WXUNUSED(event) );
	void OnSocketEvent( wxSocketEvent&amp; event );
	void OnClientConnect( wxSocketEvent&amp; event );

    protected:
	virtual void OnButton2_closeButtonClicked(wxCommandEvent&amp; event);
    virtual void OnButton1_startButtonClicked(wxCommandEvent&amp; event);

	wxSocketBase *m_ClientSockets[MAX_CLIENTS];
	wxSocketServer *m_pSocketServer;
	ClientThread *m_pClientThread;
	wxCriticalSection m_csClientThreadCS;

	friend class ClientThread;

	DECLARE_EVENT_TABLE();
};
#endif // MAINFRAME_H
</code></pre>
<pre><code>#include &quot;MainFrame.h&quot;
#include &lt;wx/msgdlg.h&gt;
#include &lt;wx/log.h&gt; 

//------------------------------------------------------------
//------------------------------------------------------------
// Klasse: MainFrame
//------------------------------------------------------------
//------------------------------------------------------------

MainFrame::MainFrame(wxWindow* parent)
    : MainFrameBaseClass(parent)
{
   m_pSocketServer = 0;

   for ( int i = 0; i &lt; MAX_CLIENTS; i++ )
   {
	   m_ClientSockets[i] = 0;
   }
}

MainFrame::~MainFrame()
{

}

void MainFrame::OnButton1_startButtonClicked( wxCommandEvent&amp; event )
{	
	OnServerStart( event );
}

void MainFrame::OnButton2_closeButtonClicked( wxCommandEvent&amp; event )
{
	Close( true );
}

BEGIN_EVENT_TABLE(MainFrame, wxFrame)
   EVT_BUTTON(SERVER_START, MainFrame::OnServerStart)
   EVT_SOCKET(SERVER_ID, MainFrame::OnServerEvent)
   EVT_SOCKET(SOCKET_ID, MainFrame::OnSocketEvent)
END_EVENT_TABLE()

void MainFrame::OnServerStart( wxCommandEvent&amp; WXUNUSED(event) )
{
	wxIPV4address addr;

	try
	{
		// Create the address
		addr.Hostname( m_textCtrl1_IP -&gt; GetValue() );
		addr.Service( m_textCtrl2_Port -&gt; GetValue() );

		// Create the socket
		m_pSocketServer = new wxSocketServer( addr );

		// Check if the server is listening
		if ( !m_pSocketServer -&gt; IsOk() )
		{
		   return;	
		}

		// Set up the event handler
		m_pSocketServer -&gt; SetEventHandler( *this, SERVER_ID );
		m_pSocketServer -&gt; SetNotify( wxSOCKET_CONNECTION_FLAG );
		m_pSocketServer -&gt; Notify( true );
	}
	catch (...)
	{

	}
}

void MainFrame::OnServerEvent( wxSocketEvent&amp; WXUNUSED(event) )
{	
	try
	{
		// Check the array if a free Socket is available
		for ( int i = 0; i &lt; MAX_CLIENTS; i++ )
		{
			if ( m_ClientSockets[i] == 0 )
			{
				m_ClientSockets[i] = new wxSocketBase();
			}

			if ( m_ClientSockets[i] -&gt; IsDisconnected() )
			{
			   // Accept the new conncetion and get the socket pointer
			   m_ClientSockets[i] = m_pSocketServer -&gt; Accept( true );

			   // Tell the new socket how and where to process its events
		       m_ClientSockets[i] -&gt; SetEventHandler( *this, SOCKET_ID );
		       m_ClientSockets[i] -&gt; SetNotify( wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG );
		       m_ClientSockets[i] -&gt; Notify( true );
			   break;	
			}
		}
	}
	catch (...)
	{

	}
}

void MainFrame::OnSocketEvent( wxSocketEvent&amp; event )
{	
	try
	{
	   m_pClientThread = new ClientThread( this );

	   if ( m_pClientThread -&gt; Run() != wxTHREAD_NO_ERROR )
	   {
		   wxLogError( &quot;Can't create the thread!&quot; );
		   delete m_pClientThread;
		   m_pClientThread = NULL;
	   }
	}
	catch (...)
	{

	}
}

void MainFrame::OnClientConnect( wxSocketEvent&amp; event )
{
	wxSocketBase *pSocket = 0;
	wxString IP;
	wxIPV4address addr;
	char buffer[50];

	try
	{
		// The socket that had the event
		pSocket = event.GetSocket();

		// Handle the socket events
		switch ( event.GetSocketEvent() )
		{
		   case wxSOCKET_INPUT: 
				m_pSocketServer -&gt; GetPeer( addr );
				IP = addr.Hostname();
				m_richTextCtrl_Client_List -&gt; AppendText( IP );
                buffer[0] = 'H';
				buffer[1] = 'i';
				buffer[2] = '\0';
				pSocket -&gt; Write( buffer, sizeof( buffer ) ); break;
		   case wxSOCKET_LOST: 
			    m_richTextCtrl_Client_List -&gt; Clear();
				pSocket -&gt; Destroy(); break;
		}
	}
	catch (...)
	{

	}	
}
</code></pre>
<p>2.) ClientThread: Eine Klasse für Threads zum bearbeiten von Client-Anfragen (Bei Threads bin ich aber noch am einlesen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> )</p>
<pre><code>#ifndef CLIENT_THREAD_H
#define CLIENT_THREAD_H
#include &lt;wx/thread.h&gt;

//------------------------------------------------------------
//------------------------------------------------------------
// Klasse: ClientThread
//------------------------------------------------------------
//------------------------------------------------------------

class ClientThread : public wxThread
{	
   public:
   ClientThread( MainFrame *pHandler );
   ~ClientThread();	

   protected:
   virtual wxThread::ExitCode Entry();
   MainFrame *m_pHandler;
};
#endif // CLIENT_THREAD_H
</code></pre>
<pre><code>#include &quot;ClientThread.h&quot;

//------------------------------------------------------------
//------------------------------------------------------------
// Klasse: ClientThread
//------------------------------------------------------------
//------------------------------------------------------------

ClientThread::ClientThread
( MainFrame *pHandler ) :
   m_pHandler( pHandler )
{

}

ClientThread::~ClientThread()
{
	wxCriticalSectionLocker enter( m_pHandler -&gt; m_csClientThreadCS );
   	m_pHandler -&gt; m_pClientThread = NULL;
}

wxThread::ExitCode ClientThread::Entry()
{	
	//m_pHandler -&gt; OnClientConnect()

	return 0;
}
</code></pre>
<p>Mein Problem ist jetzt wie folgt:<br />
Beide Klassen besitzen in der jeweiligen Header-Datei eine Membervariable vom jeweils anderen Typ.</p>
<p>MainFrame =&gt; ClientThread *m_pClientThread;<br />
ClientThread =&gt; MainFrame *m_pHandler;</p>
<p>Ich kann aber hier in diesem Fall ja nicht einfach die Header-Dateien includieren, da die &quot;ClientThread.h&quot; und die &quot;MainFrame.h&quot; bereits von den CPP-Dateien includiert werden. Die Include-Guards lassen das ja nicht zu.</p>
<p>Deshalb bekomme ich derzeit beim Übersetzen den Fehler:<br />
&quot;MainFrame.h:38:2: error: ClientThread does not name a type&quot;</p>
<p>Wie löse ich das am Besten? Es tut mir Leid, wenn ich mich dumm anstelle - Ich hoffe, ihr könnt mir helfen. PS: Mein erster Post im Forum ^^.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2474550</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2474550</guid><dc:creator><![CDATA[Haio]]></dc:creator><pubDate>Sat, 07 Nov 2015 19:25:39 GMT</pubDate></item><item><title><![CDATA[Reply to Frage: Klassen richtig einbinden on Sat, 07 Nov 2015 19:36:01 GMT]]></title><description><![CDATA[<p>Das geht mit Vorwärtsdeklarationen. Der Typ ist damit zwar noch nicht definiert, aber dem Compiler bekanntgegeben, sodass du Zeiger und Referenzen auf diesen Typ erstellen kannst. Zum instanziieren braucht der Compiler aber die konkrete Definition.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2474551</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2474551</guid><dc:creator><![CDATA[Techel]]></dc:creator><pubDate>Sat, 07 Nov 2015 19:36:01 GMT</pubDate></item><item><title><![CDATA[Reply to Frage: Klassen richtig einbinden on Sat, 07 Nov 2015 19:40:29 GMT]]></title><description><![CDATA[<p>Wie sehe das dann richtig aus?<br />
Bzw. wo muss ich das dann am Besten machen?</p>
<p>In MainFrame:</p>
<pre><code>#ifndef MAINFRAME_H
#define MAINFRAME_H
#include &quot;wxcrafter.h&quot;
#include &lt;wx/socket.h&gt;
#define MAX_CLIENTS 5
class ClientThread;

//------------------------------------------------------------
//------------------------------------------------------------
// Klasse: MainFrame
//------------------------------------------------------------
//------------------------------------------------------------

class MainFrame : public MainFrameBaseClass
{
    public:
    MainFrame(wxWindow* parent);
    virtual ~MainFrame();

    enum
    {
        SERVER_START,
        SERVER_ID,
        SOCKET_ID
    };

    public:
    void OnServerStart( wxCommandEvent&amp; WXUNUSED(event) );
    void OnServerEvent( wxSocketEvent&amp; WXUNUSED(event) );
    void OnSocketEvent( wxSocketEvent&amp; event );
    void OnClientConnect( wxSocketEvent&amp; event );

    protected:
    virtual void OnButton2_closeButtonClicked(wxCommandEvent&amp; event);
    virtual void OnButton1_startButtonClicked(wxCommandEvent&amp; event);

    wxSocketBase *m_ClientSockets[MAX_CLIENTS];
    wxSocketServer *m_pSocketServer;
    ClientThread *m_pClientThread;
    wxCriticalSection m_csClientThreadCS;

    friend class ClientThread;

    DECLARE_EVENT_TABLE();
};
#endif // MAINFRAME_H
</code></pre>
<p>oder in ClientThread:</p>
<pre><code>#ifndef CLIENT_THREAD_H
#define CLIENT_THREAD_H
#include &lt;wx/thread.h&gt;
class MainFrame;

//------------------------------------------------------------
//------------------------------------------------------------
// Klasse: ClientThread
//------------------------------------------------------------
//------------------------------------------------------------

class ClientThread : public wxThread
{  
   public:
   ClientThread( MainFrame *pHandler );
   ~ClientThread();

   protected:
   virtual wxThread::ExitCode Entry();
   MainFrame *m_pHandler;
};
#endif // CLIENT_THREAD_H
</code></pre>
<p>Oder in beiden? Und was heißt dann genau &quot;konkrete Definition&quot;?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2474554</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2474554</guid><dc:creator><![CDATA[Haio]]></dc:creator><pubDate>Sat, 07 Nov 2015 19:40:29 GMT</pubDate></item><item><title><![CDATA[Reply to Frage: Klassen richtig einbinden on Mon, 09 Nov 2015 12:13:17 GMT]]></title><description><![CDATA[<p>Forward declaration:<br />
<a href="https://en.wikipedia.org/wiki/Circular_dependency" rel="nofollow">https://en.wikipedia.org/wiki/Circular_dependency</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2474723</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2474723</guid><dc:creator><![CDATA[SuchmaschinenNutzer]]></dc:creator><pubDate>Mon, 09 Nov 2015 12:13:17 GMT</pubDate></item><item><title><![CDATA[Reply to Frage: Klassen richtig einbinden on Mon, 09 Nov 2015 13:57:10 GMT]]></title><description><![CDATA[<p>Haio schrieb:</p>
<blockquote>
<p>Wie sehe das dann richtig aus?<br />
Bzw. wo muss ich das dann am Besten machen?</p>
</blockquote>
<p>Hast du schon richtig gemacht. Man muss es in mindestens einer Header Datei machen aber beide schadet auch nicht. Es hat sogar eher Vorteile, da weniger Header mit in die gleiche Compilation Unit gezogen werden und sich Compilezeiten verbessern können. Einziger Nachteil wäre wenn man von außen an die Pointer kommt (weil public oder durch eine Memberfunktion) weil man dann an diesen Stellen auch manuell den zweiten Header includen muss. Für private/protected Membervariablen die Pointer auf eigene Klassen sind finde ich es eine gute Angewohnheit einfach immer eine Forward Declaration zu nutzen.</p>
<p>Haio schrieb:</p>
<blockquote>
<p>Und was heißt dann genau &quot;konkrete Definition&quot;?</p>
</blockquote>
<pre><code>class X;  // Vorwärtsdeklaration

class X  // konkrete Definition
{
  // Stuff
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2474741</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2474741</guid><dc:creator><![CDATA[sebi707]]></dc:creator><pubDate>Mon, 09 Nov 2015 13:57:10 GMT</pubDate></item></channel></rss>