<?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[Globaler Zugriff auf Objekt einer abgeleiteten Klasse]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich stoße gerade auf ein Problem und hoffe auf euren Rat, wie man es am elegantesten löst.</p>
<p>Ich habe eine abstr. Basisklasse <strong>SchedChannelA</strong> mit einigen bereits implementierten Funktionen und einigen Membervariablen, u.a. <strong>m_NextCall.</strong> Von dieser werden mehrere Klassen abgeleitet. Von einigen dieser abgel. Klassen sollen mehrere Objekte erstellt werden können, aber es soll eine Klasse geben <strong>(SocketSrvChn),</strong> die nur einmal erstellt werden kann, und eine abstrakte Klasse <strong>(OutputChnA),</strong> von der andere Klassen abgeleitet werden, die auch nur einmal erstellt werden können (<strong>HtmlOutputChn, DataOutputChn, HeaderOutputChn</strong>).</p>
<p>Nachdem ich in der obersten Basisklasse bereits einen öffentlichen Konstruktor mit mehreren Parametern angegeben habe, kann ich das Singleton-Entwurfsmuster wohl nicht mehr verwenden, oder? Wobei ich mich im Programm auch gut selbst drum kümmern kann dass nur eine Instanz erstellt wird.</p>
<p>Aber das schwierigere Problem ist , dass ich eine globale Zugriffsmöglichkeit auf die Objekte brauche, die nur einmal erstellt werden (zumindest für die Klasse DataOutputChn).</p>
<p>Kann ich dazu in <strong>OutputChnA</strong> eine statische Memberfunktion verwenden, die die Variable m_NextCall setzen kann, so dass diese Variable für alle Objekte der Klasse DataOutputChn immer gleich wäre (da ich ja von der Klasse sowieso nur ein Objekt erstellen werde)?<br />
Nachdem die Variable in <strong>SchedChannelA</strong> nicht &quot;static&quot; deklariert ist, müsste ich in der Klasse &quot;OutputChnA&quot; noch einmal eine &quot;static m_NextCall&quot;-Variable deklarieren und die alte Variable damit überschreiben.<br />
Aber gibt dann die Funktion <strong>SchedChannelA::getNextCall()</strong> auch den Wert der &quot;richtigen&quot; Variable zurück?</p>
<p>Oder ist es der bessere Weg, in OutputChnA eine neue Variable &quot;static m_myNextCall&quot; festzulegen, und eine Memberfunktion &quot;static setNextCall()&quot; zu schreiben?<br />
Wenn ich in SchedChannelA dann die Methode getNextCall() als &quot;virtual&quot; deklariere, kann ich in OutputChnA die Methode überschreiben und anstelle von m_NextCall m_myNextCall zurückgeben.<br />
Die Lösung sollte funktionieren, kommt mir aber irgendwie unsauber vor.</p>
<p>Weiß jemand eine geschickte Lösung für dieses Problem?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/244366/globaler-zugriff-auf-objekt-einer-abgeleiteten-klasse</link><generator>RSS for Node</generator><lastBuildDate>Sat, 19 Sep 2026 10:52:25 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/244366.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 29 Jun 2009 09:32:05 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Globaler Zugriff auf Objekt einer abgeleiteten Klasse on Mon, 29 Jun 2009 09:32:05 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich stoße gerade auf ein Problem und hoffe auf euren Rat, wie man es am elegantesten löst.</p>
<p>Ich habe eine abstr. Basisklasse <strong>SchedChannelA</strong> mit einigen bereits implementierten Funktionen und einigen Membervariablen, u.a. <strong>m_NextCall.</strong> Von dieser werden mehrere Klassen abgeleitet. Von einigen dieser abgel. Klassen sollen mehrere Objekte erstellt werden können, aber es soll eine Klasse geben <strong>(SocketSrvChn),</strong> die nur einmal erstellt werden kann, und eine abstrakte Klasse <strong>(OutputChnA),</strong> von der andere Klassen abgeleitet werden, die auch nur einmal erstellt werden können (<strong>HtmlOutputChn, DataOutputChn, HeaderOutputChn</strong>).</p>
<p>Nachdem ich in der obersten Basisklasse bereits einen öffentlichen Konstruktor mit mehreren Parametern angegeben habe, kann ich das Singleton-Entwurfsmuster wohl nicht mehr verwenden, oder? Wobei ich mich im Programm auch gut selbst drum kümmern kann dass nur eine Instanz erstellt wird.</p>
<p>Aber das schwierigere Problem ist , dass ich eine globale Zugriffsmöglichkeit auf die Objekte brauche, die nur einmal erstellt werden (zumindest für die Klasse DataOutputChn).</p>
<p>Kann ich dazu in <strong>OutputChnA</strong> eine statische Memberfunktion verwenden, die die Variable m_NextCall setzen kann, so dass diese Variable für alle Objekte der Klasse DataOutputChn immer gleich wäre (da ich ja von der Klasse sowieso nur ein Objekt erstellen werde)?<br />
Nachdem die Variable in <strong>SchedChannelA</strong> nicht &quot;static&quot; deklariert ist, müsste ich in der Klasse &quot;OutputChnA&quot; noch einmal eine &quot;static m_NextCall&quot;-Variable deklarieren und die alte Variable damit überschreiben.<br />
Aber gibt dann die Funktion <strong>SchedChannelA::getNextCall()</strong> auch den Wert der &quot;richtigen&quot; Variable zurück?</p>
<p>Oder ist es der bessere Weg, in OutputChnA eine neue Variable &quot;static m_myNextCall&quot; festzulegen, und eine Memberfunktion &quot;static setNextCall()&quot; zu schreiben?<br />
Wenn ich in SchedChannelA dann die Methode getNextCall() als &quot;virtual&quot; deklariere, kann ich in OutputChnA die Methode überschreiben und anstelle von m_NextCall m_myNextCall zurückgeben.<br />
Die Lösung sollte funktionieren, kommt mir aber irgendwie unsauber vor.</p>
<p>Weiß jemand eine geschickte Lösung für dieses Problem?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1734431</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1734431</guid><dc:creator><![CDATA[Radix]]></dc:creator><pubDate>Mon, 29 Jun 2009 09:32:05 GMT</pubDate></item><item><title><![CDATA[Reply to Globaler Zugriff auf Objekt einer abgeleiteten Klasse on Mon, 29 Jun 2009 09:55:15 GMT]]></title><description><![CDATA[<p>Hallo Radix,</p>
<p>Du kannst in jeder Klasse (Basis oder abgeleitete Klasse) eine statische Farbrikmethode implementieren. Dann kannst Du für jede Klasse die Objekterzeugung und die Anzahl der Objekte steuern.</p>
<p>Ich verpacke dazu die Objekte in std::tr1::shared_ptr (bzw. boost::shared_ptr).</p>
<pre><code class="language-cpp">//Base.h:

#include &lt;memory&gt; // oder &quot;boost/Smart_Ptr.hpp&quot;, wenn kein tr1 vorhanden

class Base;
typedef std::tr1::shared_ptr&lt;Base&gt; BasePtr; // oder boost::shared_ptr&lt;&gt;

class Base{

   private:
      virtual Base( /* Parameter für Base */ ); // keine direkte Objekterzeugung

   //...
   public:
      static BasePtr GetInstance( /* Parameter für Base */ ){

          // hier die Objekterzeugung für Base-Objekte
          // durchführen und steuern
      }
};
</code></pre>
<pre><code class="language-cpp">// Derived.h:
#include &quot;Base.h&quot;

class Derived;
typedef std::tr1::shared_ptr&lt;Derived&gt; DerivedPtr;

class Derived : public Base{

   private:
      virtual Derived( /* Parameter für Derived */ ); // keine direkte Objekterzeugung

   //...
   public:
      static DerivedPtr GetInstance( /* Parameter für Derived */ ){

          // hier die Objekterzeugung für Derived-Objekte
          // durchführen und steuern
      }
};
</code></pre>
<pre><code class="language-cpp">// main.h:

#include &quot;Base.h&quot;
#include &quot;Derived.h&quot;

int main(){

   // ...

   BasePtr myBase = Base::GetInstance(/*Parameter*/);
   myBase-&gt;...;

   // ...

   DerivedPtr myDerived = Derived::GetInstance(/*Parameter*/);
   myDerived-&gt;...;
   return 0;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1734442</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1734442</guid><dc:creator><![CDATA[Roger Wilco]]></dc:creator><pubDate>Mon, 29 Jun 2009 09:55:15 GMT</pubDate></item><item><title><![CDATA[Reply to Globaler Zugriff auf Objekt einer abgeleiteten Klasse on Mon, 29 Jun 2009 11:48:15 GMT]]></title><description><![CDATA[<p>Ich dachte jetzt, die Lösung wäre einfach, mich selbst um die einmalige Erstellung zu kümmern und einfach eine &quot;static getInstance()&quot;-Methode zu verwenden, allerdings gibt's ein ziemlich seltsames Verhalten.</p>
<p>Um getInstance() ohne Parameter aufrufen zu können, aber die Erstellung des Objekts mit Parametern machen zu können, kümmere ich mich selbst darum dass es nur eine Instanz gibt.<br />
getInstance() dient also nur dem globalen Zugriff.</p>
<p>Hier mal mein Code:</p>
<pre><code class="language-cpp">// SchedChannelA.h
class SchedChannelA
{
	public: 
		SchedChannelA(); // setzt default werte fuer ein paar member var
		string getChnName();
		long long unsigned int getNextCallTime();
	private:
		long long unsigned int m_NextCall;
		string m_ChnName;
};

// OutputChnA.h
class OutputChnA : public SchedChannelA
{
	public:
		void triggerCall();
		OutputChnA(std::string filenameP, std::vector&lt;MeasChnA*&gt; MeasChnVectP); 
		static OutputChnA* getInstance();
	protected:
		static OutputChnA* m_instance;

}

//OutputChnA.cpp

OutputChnA* OutputChnA::m_instance = NULL;

OutputChnA::OutputChnA(string filenameP, vector&lt;MeasChnA*&gt; MeasChnVectP):
    /* ... */
{
    m_instance = this;
}

void OutputChnA::triggerCall()
{
    m_NextCall = Clock::getTimestamp();
}

OutputChnA* OutputChnA::getInstance()
{
    if( m_instance )
        return m_instance;
    else
        /* ... */
}

// derived classes: HtmlOutputChn mit ChnName = &quot;HtmlOutput&quot;, DataOutputChn mit ChnName = &quot;DataOutput&quot;, ...

// main.cpp
int main()
{
/* ... */

    OutputChnA* chnPtr = DataOutputChn::getInstance();
    chnPtr-&gt;triggerCall();
    cout &lt;&lt; &quot;ChnName: &quot; &lt;&lt; chnPtr-&gt;getChnName() &lt;&lt; &quot;\tSet trigger to: &quot; &lt;&lt; chnPtr-&gt;getNextCallTime() &lt;&lt; endl;
}
</code></pre>
<p>In main() erhalte ich jetzt zwar für <strong>chnPtr-&gt;getNextCallTime()</strong> den gerade gesetzten Wert, aber für <strong>chnPtr-&gt;getChnName()</strong> den Wert &quot;HtmlOutput&quot;. In meinem DataOutputChn-Objekt habe ich dagegen einen unveränderten NextCall-Wert stehen (die Werte des DataOutputChn kann ich sehen, weil der Channel auch in einem std::vector&lt;SchedChnA*&gt; liegt, dessen Inhalt ich mir komplett ausgeben lasse).</p>
<p>Irgendwie ist bei mir also noch ganz schön der Wurm drin.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1734496</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1734496</guid><dc:creator><![CDATA[Radix]]></dc:creator><pubDate>Mon, 29 Jun 2009 11:48:15 GMT</pubDate></item><item><title><![CDATA[Reply to Globaler Zugriff auf Objekt einer abgeleiteten Klasse on Mon, 29 Jun 2009 12:33:09 GMT]]></title><description><![CDATA[<p>Zeig mal bitte den Code, wo Du ChnName für die OutputChnA-Objekte setzt.</p>
<p>Außerdem: Denk daran, dass Dein Singleton-Code so nicht threadsafe ist!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1734522</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1734522</guid><dc:creator><![CDATA[Roger Wilco]]></dc:creator><pubDate>Mon, 29 Jun 2009 12:33:09 GMT</pubDate></item><item><title><![CDATA[Reply to Globaler Zugriff auf Objekt einer abgeleiteten Klasse on Mon, 29 Jun 2009 13:02:16 GMT]]></title><description><![CDATA[<p>Roger Wilco schrieb:</p>
<blockquote>
<p>Zeig mal bitte den Code, wo Du ChnName für die OutputChnA-Objekte setzt.</p>
</blockquote>
<p>Diese Variable wird immer im Konstruktor der konkret ausgeprägten Klassen gesetzt:</p>
<pre><code class="language-cpp">HtmlOutputChn::HtmlOutputChn(string filenameP, vector&lt;MeasChnA*&gt; MeasChnVectP):OutputChnA(filenameP, MeasChnVectP)
{
    m_ChnName = &quot;HtmlOutput&quot;;
    m_CallIntv = 20*1000; // for testing purpose: 20 sec in msec
}

DataOutputChn::DataOutputChn(string filenameP, vector&lt;MeasChnA*&gt; MeasChnVectP):OutputChnA(filenameP, MeasChnVectP)
{
    m_ChnName = &quot;DataOutput&quot;;
}

// Konstruktor der abstrakten Basisklasse
OutputChnA::OutputChnA(string filenameP, vector&lt;MeasChnA*&gt; MeasChnVectP):
    m_spFileWriter(new FileWriter(filenameP, eOverwrite)),m_MeasChnVect(MeasChnVectP)
{
    m_isDisplayChn = false;
    m_instance = this;
}
</code></pre>
<blockquote>
<p>Außerdem: Denk daran, dass Dein Singleton-Code so nicht threadsafe ist!</p>
</blockquote>
<p>Das ist okay, ich verwende keine Threads.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1734532</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1734532</guid><dc:creator><![CDATA[Radix]]></dc:creator><pubDate>Mon, 29 Jun 2009 13:02:16 GMT</pubDate></item><item><title><![CDATA[Reply to Globaler Zugriff auf Objekt einer abgeleiteten Klasse on Mon, 29 Jun 2009 13:13:29 GMT]]></title><description><![CDATA[<p>Aber m_ChnName ist doch ein privates Attribut der Basisklasse SchedChannelA. Dann kannst Du doch darauf gar nicht zugreifen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1734538</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1734538</guid><dc:creator><![CDATA[Roger Wilco]]></dc:creator><pubDate>Mon, 29 Jun 2009 13:13:29 GMT</pubDate></item><item><title><![CDATA[Reply to Globaler Zugriff auf Objekt einer abgeleiteten Klasse on Mon, 29 Jun 2009 13:20:04 GMT]]></title><description><![CDATA[<p>Ahhh...'tschuldigung, ein Malheur beim Code-Kürzen. Die Attribute sind in der SchedChannelA-Klasse nicht private, sondern protected deklariert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1734543</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1734543</guid><dc:creator><![CDATA[Radix]]></dc:creator><pubDate>Mon, 29 Jun 2009 13:20:04 GMT</pubDate></item><item><title><![CDATA[Reply to Globaler Zugriff auf Objekt einer abgeleiteten Klasse on Mon, 29 Jun 2009 13:58:54 GMT]]></title><description><![CDATA[<p>Ok, würde ich zwar als privates Attribut belassen und denn ChnName als Aufrufparameter des SchedChannelA-Konstruktors übergeben, aber das löst das Problem nicht.</p>
<p>Bist Du mal mit dem Debugger den Code durchgegangen? So wüsste ich nicht, woran das liegt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1734569</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1734569</guid><dc:creator><![CDATA[Roger Wilco]]></dc:creator><pubDate>Mon, 29 Jun 2009 13:58:54 GMT</pubDate></item><item><title><![CDATA[Reply to Globaler Zugriff auf Objekt einer abgeleiteten Klasse on Tue, 30 Jun 2009 10:47:22 GMT]]></title><description><![CDATA[<p>Roger Wilco schrieb:</p>
<blockquote>
<p>Ok, würde ich zwar als privates Attribut belassen und denn ChnName als Aufrufparameter des SchedChannelA-Konstruktors übergeben, aber das löst das Problem nicht.</p>
</blockquote>
<p>Da fehlt mir manchmal einfach die Erfahrung um das &quot;richtig&quot; zu machen. Ich dachte, protected-Vererbung wäre eleganter weil ich sonst in den abgeleiteten Klassen ggf. über den vollqualifizierten Namen auf die Variable zugreifen muss.</p>
<blockquote>
<p>Bist Du mal mit dem Debugger den Code durchgegangen? So wüsste ich nicht, woran das liegt.</p>
</blockquote>
<p>Bin ich, aber da hab ich auch nichts gesehen was mich weitergebracht hätte. Ich hab jetzt zwar nicht die ultimative Lösung, aber ein Workaround, indem ich die entspr. Funktionen von OutputChnA nach DataOutputChn verlegt habe. Schön ist's nicht, aber es geht - solange ich die Funktion nur in dieser Klasse brauche.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1734893</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1734893</guid><dc:creator><![CDATA[Radix]]></dc:creator><pubDate>Tue, 30 Jun 2009 10:47:22 GMT</pubDate></item></channel></rss>