<?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[operator&amp;lt;&amp;lt; für eine Logger Klasse]]></title><description><![CDATA[<p>Hallo, ich versuche eine Logger Klasse zu schreiben. Ich nutze dafür auch ein Singleton Template von welchem der Logger erbt. Um die Ausgaben auch direkt zu flushen wollte ich gern den operator&lt;&lt; überschreiben um direkt</p>
<pre><code class="language-cpp">logger::instance() &lt;&lt; &quot;test&quot;;
</code></pre>
<p>schreiben zu können. Wenn ich aber genau eine solche Zeile einfüge, bekomme ich Fehlermeldungen.</p>
<p>Hier die beiden Klassen:</p>
<pre><code class="language-cpp">#ifndef __SINGLETON_H__
#define __SINGLETON_H__

#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;string&gt;

template &lt;typename C&gt; class Singleton {
public:
	static C* instance () {
		if (!_instance)
			_instance = new C ();
		return _instance;
	}
	virtual ~Singleton () {
		_instance = 0;
	}
private:
	static C* _instance;
protected:
	Singleton () { }
};
template &lt;typename C&gt; C* Singleton &lt;C&gt;::_instance = 0;

class logger : public Singleton&lt; logger &gt; {
	friend class Singleton &lt;logger&gt;;
public:
	~logger();
	static logger* instance() {
		return Singleton &lt;logger&gt;::instance();
	}
protected:
	logger();
public:
	void open(); 
	void close();
	std::ofstream log;
	template &lt;typename T&gt; logger&amp; operator&lt;&lt; (T t);
};

inline void logger::open() { this-&gt;log.open(&quot;logfile.txt&quot;, std::ios_base::app); };
inline void logger::close() { this-&gt;log.close(); }
inline logger::logger() : Singleton &lt;logger&gt;() { this-&gt;open(); }
inline logger::~logger() { this-&gt;close(); }
template &lt;typename T&gt; logger&amp; logger::operator&lt;&lt;(T t) {
	log &lt;&lt; t &lt;&lt; flush;
	return *this;
}

#endif
</code></pre>
<p>Die Fehlermeldungen lauten</p>
<pre><code class="language-cpp">error C2296: '&lt;&lt;': Ungültig, da der linke Operand vom Typ 'logger *' ist
error C2297: '&lt;&lt;': Ungültig, da der rechte Operand vom Typ 'const char [5]' ist
</code></pre>
<p>Hat jemand einen Tipp wie ich den operator&lt;&lt; definieren muss damit ich ihn so nutzen kann? Vielen Dank im Voraus.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/212270/operator-lt-lt-für-eine-logger-klasse</link><generator>RSS for Node</generator><lastBuildDate>Wed, 14 Oct 2026 17:24:28 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/212270.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 03 May 2008 23:41:40 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to operator&amp;lt;&amp;lt; für eine Logger Klasse on Sat, 03 May 2008 23:41:40 GMT]]></title><description><![CDATA[<p>Hallo, ich versuche eine Logger Klasse zu schreiben. Ich nutze dafür auch ein Singleton Template von welchem der Logger erbt. Um die Ausgaben auch direkt zu flushen wollte ich gern den operator&lt;&lt; überschreiben um direkt</p>
<pre><code class="language-cpp">logger::instance() &lt;&lt; &quot;test&quot;;
</code></pre>
<p>schreiben zu können. Wenn ich aber genau eine solche Zeile einfüge, bekomme ich Fehlermeldungen.</p>
<p>Hier die beiden Klassen:</p>
<pre><code class="language-cpp">#ifndef __SINGLETON_H__
#define __SINGLETON_H__

#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;string&gt;

template &lt;typename C&gt; class Singleton {
public:
	static C* instance () {
		if (!_instance)
			_instance = new C ();
		return _instance;
	}
	virtual ~Singleton () {
		_instance = 0;
	}
private:
	static C* _instance;
protected:
	Singleton () { }
};
template &lt;typename C&gt; C* Singleton &lt;C&gt;::_instance = 0;

class logger : public Singleton&lt; logger &gt; {
	friend class Singleton &lt;logger&gt;;
public:
	~logger();
	static logger* instance() {
		return Singleton &lt;logger&gt;::instance();
	}
protected:
	logger();
public:
	void open(); 
	void close();
	std::ofstream log;
	template &lt;typename T&gt; logger&amp; operator&lt;&lt; (T t);
};

inline void logger::open() { this-&gt;log.open(&quot;logfile.txt&quot;, std::ios_base::app); };
inline void logger::close() { this-&gt;log.close(); }
inline logger::logger() : Singleton &lt;logger&gt;() { this-&gt;open(); }
inline logger::~logger() { this-&gt;close(); }
template &lt;typename T&gt; logger&amp; logger::operator&lt;&lt;(T t) {
	log &lt;&lt; t &lt;&lt; flush;
	return *this;
}

#endif
</code></pre>
<p>Die Fehlermeldungen lauten</p>
<pre><code class="language-cpp">error C2296: '&lt;&lt;': Ungültig, da der linke Operand vom Typ 'logger *' ist
error C2297: '&lt;&lt;': Ungültig, da der rechte Operand vom Typ 'const char [5]' ist
</code></pre>
<p>Hat jemand einen Tipp wie ich den operator&lt;&lt; definieren muss damit ich ihn so nutzen kann? Vielen Dank im Voraus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1502862</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1502862</guid><dc:creator><![CDATA[ElClowno]]></dc:creator><pubDate>Sat, 03 May 2008 23:41:40 GMT</pubDate></item><item><title><![CDATA[Reply to operator&amp;lt;&amp;lt; für eine Logger Klasse on Sat, 03 May 2008 23:56:57 GMT]]></title><description><![CDATA[<p>lass instance() einfach eine referenz zurückgeben:</p>
<pre><code class="language-cpp">static C&amp; instante ()
{
  if (!_instance()) _instance = new C();
  return *_instance;
}
</code></pre>
<p>btw. ich finde bei dir kein delete für _instance. nur null setzen reicht nicht.<br />
außerdem ist das nette am CRTP, dass du den destruktor gerade *nicht* virtuell machen musst, weil das delete im destruktor von Singleton&lt;logger&gt; automatisch logger::~logger aufruft. und andersrum brauchst du in logger auch keine methode instance().</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1502869</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1502869</guid><dc:creator><![CDATA[queer_boy]]></dc:creator><pubDate>Sat, 03 May 2008 23:56:57 GMT</pubDate></item><item><title><![CDATA[Reply to operator&amp;lt;&amp;lt; für eine Logger Klasse on Sun, 04 May 2008 00:28:48 GMT]]></title><description><![CDATA[<p>Nur so nebenbei: Wieso ist dein Logger ein Singleton? Wieso verwährst du dir damit die Möglichkeit, mehrere Logger zu benutzen?<br />
Singletons sind zu 99% überflüssig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1502870</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1502870</guid><dc:creator><![CDATA[this-*gt*that]]></dc:creator><pubDate>Sun, 04 May 2008 00:28:48 GMT</pubDate></item><item><title><![CDATA[Reply to operator&amp;lt;&amp;lt; für eine Logger Klasse on Sun, 04 May 2008 08:15:59 GMT]]></title><description><![CDATA[<p>Super, jetzt funktioniert es. Jetzt muss ich nur noch angucken warum genau <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":/"
      alt="😕"
    /></p>
<p>queer_boy schrieb:</p>
<blockquote>
<p>btw. ich finde bei dir kein delete für _instance. nur null setzen reicht nicht.<br />
außerdem ist das nette am CRTP, dass du den destruktor gerade *nicht* virtuell machen musst, weil das delete im destruktor von Singleton&lt;logger&gt; automatisch logger::~logger aufruft. und andersrum brauchst du in logger auch keine methode instance().</p>
</blockquote>
<p>Ich hatte das Singleton und seine Benutzung irgendwo im Netz gefunden. Es sah weniger verwirrend aus als die meisten Anderen. Und ich hab mir ehrlich gesagt nicht viel Kopf um die Richtigkeit gemacht. Aber du hast natürlich recht, die logger::instance() Funktion ist überflüssig.<br />
Ich habe noch zwei Fragen:<br />
1. Warum ist der Unterschied virtuell oder nicht für den Destruktor in dieser Klasse wichtig? Funktionieren scheint beides.<br />
2. Ich habe nicht ganz verstanden wie du das mit dem delete meinst, kannst du das genauer erklären?</p>
<p>this-&gt;that schrieb:</p>
<blockquote>
<p>Nur so nebenbei: Wieso ist dein Logger ein Singleton? Wieso verwährst du dir damit die Möglichkeit, mehrere Logger zu benutzen?<br />
Singletons sind zu 99% überflüssig.</p>
</blockquote>
<p>In diesem Falle weil es sich um ein spezielles Problem handelt. Ich muss einen etwas nervigen Fehler in einem Projekt finden der sich aber über mehrere Klassen erstreckt. Und da dachte ich, eh ich immer nen Zeiger mitschleife und alle Funktionen änderen muss, kann ich auch mal ein Singleton ausprobieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1502906</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1502906</guid><dc:creator><![CDATA[ElClowno]]></dc:creator><pubDate>Sun, 04 May 2008 08:15:59 GMT</pubDate></item><item><title><![CDATA[Reply to operator&amp;lt;&amp;lt; für eine Logger Klasse on Sun, 04 May 2008 08:21:12 GMT]]></title><description><![CDATA[<p>ElClowno schrieb:</p>
<blockquote>
<p>this-&gt;that schrieb:</p>
<blockquote>
<p>Nur so nebenbei: Wieso ist dein Logger ein Singleton? Wieso verwährst du dir damit die Möglichkeit, mehrere Logger zu benutzen?<br />
Singletons sind zu 99% überflüssig.</p>
</blockquote>
<p>In diesem Falle weil es sich um ein spezielles Problem handelt. Ich muss einen etwas nervigen Fehler in einem Projekt finden der sich aber über mehrere Klassen erstreckt. Und da dachte ich, eh ich immer nen Zeiger mitschleife und alle Funktionen änderen muss, kann ich auch mal ein Singleton ausprobieren.</p>
</blockquote>
<p>Dann mach dir lieber ein gescheites Logsystem, das du auch wieder verwenden kannst... Dies wird nicht der letzte Fall sein bei dem du was mitloggen willst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1502908</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1502908</guid><dc:creator><![CDATA[David_pb]]></dc:creator><pubDate>Sun, 04 May 2008 08:21:12 GMT</pubDate></item><item><title><![CDATA[Reply to operator&amp;lt;&amp;lt; für eine Logger Klasse on Sun, 04 May 2008 08:25:21 GMT]]></title><description><![CDATA[<p>ElClowno schrieb:</p>
<blockquote>
<p>this-&gt;that schrieb:</p>
<blockquote>
<p>Nur so nebenbei: Wieso ist dein Logger ein Singleton? Wieso verwährst du dir damit die Möglichkeit, mehrere Logger zu benutzen?<br />
Singletons sind zu 99% überflüssig.</p>
</blockquote>
<p>In diesem Falle weil es sich um ein spezielles Problem handelt. Ich muss einen etwas nervigen Fehler in einem Projekt finden der sich aber über mehrere Klassen erstreckt. Und da dachte ich, eh ich immer nen Zeiger mitschleife und alle Funktionen änderen muss, kann ich auch mal ein Singleton ausprobieren.</p>
</blockquote>
<p>Schon mal was von debuggen gehört?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1502912</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1502912</guid><dc:creator><![CDATA[sag mal]]></dc:creator><pubDate>Sun, 04 May 2008 08:25:21 GMT</pubDate></item><item><title><![CDATA[Reply to operator&amp;lt;&amp;lt; für eine Logger Klasse on Sun, 04 May 2008 08:36:08 GMT]]></title><description><![CDATA[<p>David_pb schrieb:</p>
<blockquote>
<p>Dann mach dir lieber ein gescheites Logsystem, das du auch wieder verwenden kannst... Dies wird nicht der letzte Fall sein bei dem du was mitloggen willst.</p>
</blockquote>
<p>Ich hab im Moment nicht die Zeit das zu tun. Das Projekt existiert schon, weswegen das einflechten im Nachhinein ziemlich (zu) aufwendig ist. Und wieso ist dieses nicht wiederverwendbar, eigentlich ist es nur ein ofstream den es nur einmal gibt?</p>
<p>sag mal schrieb:</p>
<blockquote>
<p>Schon mal was von debuggen gehört?</p>
</blockquote>
<p>Ja, half hier bisher nicht wirklich weil der Fehler etwas fließend ist. Außerdem, was spricht dagegen dieses Konzept mal zu probieren wenn es in diesem Fall sinnvoll ist. Gut, ne einfache Klasse mit nem static ofstream hätte es wohl auch getan, aber ich wollte dabei auch was lernen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1502915</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1502915</guid><dc:creator><![CDATA[ElClowno]]></dc:creator><pubDate>Sun, 04 May 2008 08:36:08 GMT</pubDate></item><item><title><![CDATA[Reply to operator&amp;lt;&amp;lt; für eine Logger Klasse on Sun, 04 May 2008 11:16:20 GMT]]></title><description><![CDATA[<p>this-&gt;that schrieb:</p>
<blockquote>
<p>Nur so nebenbei: Wieso ist dein Logger ein Singleton? Wieso verwährst du dir damit die Möglichkeit, mehrere Logger zu benutzen?<br />
Singletons sind zu 99% überflüssig.</p>
</blockquote>
<p>Kannst du mir sagen wie man Logger ohne Singletons vernünftig einsetzen kann?<br />
Gerade das, also Logging, ist eine Sache wo man IMO ohne Singletons fast nicht auskommt. Allen Klassen und Funktionen einen Logger mitzugeben ist IMO halt etwas umständlich und klobig.</p>
<p>Die einzige IMO brauchbare Möglichkeit die mir dazu bis jetzt eingefallen ist, ist thread-lokale Variablen zu verwenden.<br />
Dann kann man solche Konstrukte schreiben:</p>
<pre><code class="language-cpp">void bar();

void foo()
{
    Logger l;
    LoggerScope s(l); // setzt die thread-lokale variable
    bar();
}

void bar()
{
    GetLogger() &lt;&lt; &quot;blah&quot;; // GetLogger liest die thread lokale variable
}
</code></pre>
<p>Allerdings funktioniert das auch nur genau solange bis man es irgendwo mit Callbacks aus Threads zu tun bekommt, die man nicht selbst kontrolliert.</p>
<p>Wenn du mir da also einen Tip geben könntest wäre ich sehr froh, da ich echt keine Vernünftige Lösung kenne.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1502992</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1502992</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sun, 04 May 2008 11:16:20 GMT</pubDate></item><item><title><![CDATA[Reply to operator&amp;lt;&amp;lt; für eine Logger Klasse on Sun, 04 May 2008 11:31:26 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>this-&gt;that schrieb:</p>
<blockquote>
<p>Nur so nebenbei: Wieso ist dein Logger ein Singleton? Wieso verwährst du dir damit die Möglichkeit, mehrere Logger zu benutzen?<br />
Singletons sind zu 99% überflüssig.</p>
</blockquote>
<p>Kannst du mir sagen wie man Logger ohne Singletons vernünftig einsetzen kann?</p>
</blockquote>
<p>Kann ich, auch wenn ich die Singletonvariante nicht ablehne (Eine Variante):</p>
<pre><code class="language-cpp">...
boost::shared_ptr&lt;Logger&gt; GetLogger(std::string const &amp; loggerName)
{
  static std::map&lt;std::string, boost::shared_ptr&lt;Logger&gt; &gt; LogList;
  ...
  return LogList[loggerName];
}

int main()
{
  GetLogger(&quot;error.log&quot;)-&gt;Log(&quot;Something&quot;);
}
</code></pre>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Gerade das, also Logging, ist eine Sache wo man IMO ohne Singletons fast nicht auskommt. Allen Klassen und Funktionen einen Logger mitzugeben ist IMO halt etwas umständlich und klobig.</p>
</blockquote>
<p>Deinen letzten Satz stimme ich zu, deinen ersten nicht zwangsweise. Siehe mein Beispiel. Ich habe das obere jetzt nicht irgendwie Threadsicher gemacht, aber ich schätze mal das sollte ohne Probleme machbar sein...</p>
<p>cu André</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1503006</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1503006</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Sun, 04 May 2008 11:31:26 GMT</pubDate></item><item><title><![CDATA[Reply to operator&amp;lt;&amp;lt; für eine Logger Klasse on Sun, 04 May 2008 12:23:54 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/14941">@asc</a>:<br />
Äh. Ich habe geschrieben ohne Singletons.</p>
<pre><code class="language-cpp">static std::map&lt;std::string, boost::shared_ptr&lt;Logger&gt; &gt; LogList;
</code></pre>
<p>Hallo, Singleton? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Klar kann man das Problem so ein Stück weiter schieben, das machen ja auch fast alle üblichen Logging Libraries so. Aber man kann dadurch immer noch nicht erreichen dass eine einzige Funktion in verschiedene Logfiles loggt, je nachdem aus welchem Programmteil sie aufgerufen wurde.</p>
<p>Und in Programmen die verschiedene Dinge tun, und daher u.u. auch verschiedene Logfiles schreiben wollen, wäre das eine tolle Sache.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1503051</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1503051</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sun, 04 May 2008 12:23:54 GMT</pubDate></item><item><title><![CDATA[Reply to operator&amp;lt;&amp;lt; für eine Logger Klasse on Sun, 04 May 2008 12:42:19 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/14941">@asc</a>:<br />
Äh. Ich habe geschrieben ohne Singletons.</p>
<pre><code class="language-cpp">static std::map&lt;std::string, boost::shared_ptr&lt;Logger&gt; &gt; LogList;
</code></pre>
<p>Hallo, Singleton? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
</blockquote>
<p>Ich sehe darin kein Singleton, zumindestens nicht unter den klassischen Begriff das es nur eine Instanz geben kann. Eine statische Variable alleine ist für mich noch kein Singleton - Ich kann zwar über den Methodenzugriff die Erzeugung kontrollieren, könnte den Logger aber auch beliebig anders verwenden, und mein Konstrukt sieht auch mehrere Logger vor (z.B. Einen pro Ziel).</p>
<p>cu André</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1503065</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1503065</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Sun, 04 May 2008 12:42:19 GMT</pubDate></item><item><title><![CDATA[Reply to operator&amp;lt;&amp;lt; für eine Logger Klasse on Sun, 04 May 2008 12:45:00 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Und in Programmen die verschiedene Dinge tun, und daher u.u. auch verschiedene Logfiles schreiben wollen, wäre das eine tolle Sache.</p>
</blockquote>
<p>Und? Wo ist bei meinen Einsatz die Einschränkung?</p>
<pre><code class="language-cpp">...
boost::shared_ptr&lt;Logger&gt; GetLogger(std::string const &amp; loggerName)
{
  static std::map&lt;std::string, boost::shared_ptr&lt;Logger&gt; &gt; LogList;
  // &lt;-- Prüfen ob Logger existiert, sonst ggf. neuen anlegen...
  return LogList[loggerName];
}

int main()
{
  GetLogger(&quot;error.log&quot;)-&gt;Log(&quot;Something&quot;);
  GetLogger(&quot;test.log&quot;)-&gt;Log(&quot;Something Other&quot;);
}
</code></pre>
<p>Ja, ich habe nur einen Minimalcode Geschrieben, aber sag mir bitte wo hier ein Singleton ist und NUR ein Logger?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1503068</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1503068</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Sun, 04 May 2008 12:45:00 GMT</pubDate></item></channel></rss>