<?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[getName() für Attribut vom Typ Zeiger auf eigene Klasse]]></title><description><![CDATA[<p>Hallo Community!</p>
<p>Ich programmiere meistens in c und habe deshalb noch nicht so viel Ahnung von c++.<br />
Momentan hänge ich an folgendem Problem:<br />
Klasse B hat als Attribute zwei Zeiger auf Klasse A (ich weiß nicht, wie ich das hier mit Referenzen machen kann). Klasse A hat einen std::string mit getter-Methode.</p>
<p>Ich wollte der Klasse B jetzt Getter für die Namen der Klasse-A-Objekte geben. Der Quellcode sieht so aus (Meldungen des Compilers (Visual Studio 2012) in den Kommentaren):</p>
<pre><code>#include &lt;map&gt;
#include &lt;string&gt;
using namespace std;

class KlasseA{
    string name;
public:
    KlasseA(string&amp; n) : name(n) {}
    const string&amp; sagName() const {
        return name;
    }
};

class KlasseB{
    KlasseA* elem1;
    KlasseA* elem2;
public:
    KlasseB(map&lt;string, KlasseA&amp;&gt; elems, const string&amp; name1, const string&amp; name2) : elem1(NULL), elem2(NULL) {
        map&lt;string, KlasseA&amp;&gt;::iterator found = elems.find(name1);
        if(found != elems.end())
            elem1 = &amp;(found-&gt;second);
        found = elems.find(name2);
        if(found != elems.end())
            elem2 = &amp;(found-&gt;second);
    }

    const string&amp; sagNameElem1() const {
        if(elem1)
            return elem1-&gt;sagName();
        return &quot;no such elem&quot;; // warning: Adresse einer lokalen Variablen oder eines temporären Werts wird zurückgegeben
    }
    const string&amp; sagNameElem2() const {
        if(elem2)
            return elem2-&gt;sagName();
        return NULL; // warning: Adresse einer lokalen Variablen oder eines temporären Werts wird zurückgegeben
    }
    const KlasseA&amp; sagElem1() const {
        if(elem1)
            return *elem1;
        return NULL; // error: 'return': 'int' kann nicht in 'const KlasseA &amp;' konvertiert werden
    }
    const KlasseA&amp; sagElem2() const {
        if(elem2)
            return *elem2;
        return *((KlasseA*)NULL); // Das ist doch mist...
    }
};
</code></pre>
<p>Die Variante in Zeile 27 wäre mir eigentlich am liebsten, aber dass das nicht geht ist mir auch klar.</p>
<p>Müsste ich im Konstruktor nicht die Elemente aus der map rausfischen könnte ich Referenzen statt Zeiger nehmen und hätte das Problem nicht (oder doch?).</p>
<p>Warum bekomme ich bei den Zeilen 35 und 40 unterschiedliche Meldungen? string hat doch auch keinen Konstruktor für int...</p>
<p>Wie kann man das besser/richtig lösen? Oder sollte ich das Ganze Design nochmal überdenken?</p>
<p>Edit: die const KlasseA&amp; sagElemXY()-Methoden habe ich dann als Umweg zu den Namen gedacht...</p>
<p>Viele Grüße aus Hamburg und vielen Dank für eure Hilfe!<br />
Matze</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/323561/getname-für-attribut-vom-typ-zeiger-auf-eigene-klasse</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Jul 2026 20:11:25 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/323561.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 04 Feb 2014 17:26:50 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to getName() für Attribut vom Typ Zeiger auf eigene Klasse on Tue, 04 Feb 2014 17:35:33 GMT]]></title><description><![CDATA[<p>Hallo Community!</p>
<p>Ich programmiere meistens in c und habe deshalb noch nicht so viel Ahnung von c++.<br />
Momentan hänge ich an folgendem Problem:<br />
Klasse B hat als Attribute zwei Zeiger auf Klasse A (ich weiß nicht, wie ich das hier mit Referenzen machen kann). Klasse A hat einen std::string mit getter-Methode.</p>
<p>Ich wollte der Klasse B jetzt Getter für die Namen der Klasse-A-Objekte geben. Der Quellcode sieht so aus (Meldungen des Compilers (Visual Studio 2012) in den Kommentaren):</p>
<pre><code>#include &lt;map&gt;
#include &lt;string&gt;
using namespace std;

class KlasseA{
    string name;
public:
    KlasseA(string&amp; n) : name(n) {}
    const string&amp; sagName() const {
        return name;
    }
};

class KlasseB{
    KlasseA* elem1;
    KlasseA* elem2;
public:
    KlasseB(map&lt;string, KlasseA&amp;&gt; elems, const string&amp; name1, const string&amp; name2) : elem1(NULL), elem2(NULL) {
        map&lt;string, KlasseA&amp;&gt;::iterator found = elems.find(name1);
        if(found != elems.end())
            elem1 = &amp;(found-&gt;second);
        found = elems.find(name2);
        if(found != elems.end())
            elem2 = &amp;(found-&gt;second);
    }

    const string&amp; sagNameElem1() const {
        if(elem1)
            return elem1-&gt;sagName();
        return &quot;no such elem&quot;; // warning: Adresse einer lokalen Variablen oder eines temporären Werts wird zurückgegeben
    }
    const string&amp; sagNameElem2() const {
        if(elem2)
            return elem2-&gt;sagName();
        return NULL; // warning: Adresse einer lokalen Variablen oder eines temporären Werts wird zurückgegeben
    }
    const KlasseA&amp; sagElem1() const {
        if(elem1)
            return *elem1;
        return NULL; // error: 'return': 'int' kann nicht in 'const KlasseA &amp;' konvertiert werden
    }
    const KlasseA&amp; sagElem2() const {
        if(elem2)
            return *elem2;
        return *((KlasseA*)NULL); // Das ist doch mist...
    }
};
</code></pre>
<p>Die Variante in Zeile 27 wäre mir eigentlich am liebsten, aber dass das nicht geht ist mir auch klar.</p>
<p>Müsste ich im Konstruktor nicht die Elemente aus der map rausfischen könnte ich Referenzen statt Zeiger nehmen und hätte das Problem nicht (oder doch?).</p>
<p>Warum bekomme ich bei den Zeilen 35 und 40 unterschiedliche Meldungen? string hat doch auch keinen Konstruktor für int...</p>
<p>Wie kann man das besser/richtig lösen? Oder sollte ich das Ganze Design nochmal überdenken?</p>
<p>Edit: die const KlasseA&amp; sagElemXY()-Methoden habe ich dann als Umweg zu den Namen gedacht...</p>
<p>Viele Grüße aus Hamburg und vielen Dank für eure Hilfe!<br />
Matze</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2381509</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2381509</guid><dc:creator><![CDATA[MatzeHHC]]></dc:creator><pubDate>Tue, 04 Feb 2014 17:35:33 GMT</pubDate></item><item><title><![CDATA[Reply to getName() für Attribut vom Typ Zeiger auf eigene Klasse on Wed, 05 Feb 2014 10:31:57 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>bzgl. des Designs gibt es sicherlich noch Verbesserungsmöglichkeiten.</p>
<p>Aber fangen wir mal mit dem konkreten Compilerproblem an:<br />
Wenn du eine Referenz bei einer Funktion zurückgeben willst, dann muß in allen return-Anweisungen auch eine Referenz auf den zurückzugebenden Datentypen vorhanden sein.<br />
Hier ist das Problem, daß die Klasse std::string und String-Literale (so wie du sie ja auch schon aus C kennst), nicht (ohne Konvertierung) kompatibel sind.</p>
<p>Es gibt jetzt zwei Möglichkeiten:</p>
<pre><code class="language-cpp">string sagNameElem1() const
{
    if(elem1)
        return elem1-&gt;sagName();
    return &quot;no such elem&quot;; // &lt;- hier ruft der Compiler dann explizit den std::string(const char *)-Konstruktor auf!
}
</code></pre>
<pre><code class="language-cpp">const string&amp; sagNameElem1() const
{
    static const std::string NoElem(&quot;no such elem&quot;);

    if(elem1)
        return elem1-&gt;sagName();
    return NoElem;
}
</code></pre>
<p>Alle weiteren Lösungen (bei Referenzrückgabe) mit NULL (0) sind komplett unsinnig, denn die Definition einer Referenz ist ja gerade, daß immer auf ein gültiges Objekt verwiesen wird.</p>
<p>Kürzer würde man meine obigen Lösungen übrigens so schreiben:</p>
<pre><code class="language-cpp">const string&amp; sagNameElem1() const
{
    static const std::string NoElem(&quot;no such elem&quot;);

    return elem1 ? elem1-&gt;sagName() : NoElem;
}
</code></pre>
<p>Aber wie oben schon angedeutet, finde ich das Design dieser Klassen nicht optimal. Du solltest dir unbedingt noch mal die sinnvolle Übergabe mittels &quot;const&quot; sowie &quot;&amp;&quot; (Referenz) in einem C++ Buch anschauen.</p>
<p>Als m.E. sinnvolle Verbesserungen deines Codes:</p>
<pre><code class="language-cpp">// Übergabe als const-reference
KlasseA(const string&amp; n) : name(n) {}
</code></pre>
<p>(damit man z.B. diese Klasse auch mit einem String-Literal (&quot;test&quot;) aufrufen kann)</p>
<pre><code class="language-cpp">// auch Übergabe als const-reference
KlasseB(const map&lt;string, KlasseA&amp;&gt; &amp; elems, ...)
</code></pre>
<p>(zumindestens für vor C++ 11)</p>
<p>Du solltest jedoch designtechnisch überlegen, ob deine Klassen so viel Sinn machen, wenn sich die Map ändert (oder sollen extra diese Werte einmalig aus der Map geholt werden)?<br />
Ein weiteres Stichwort könnte hier &quot;lazy evaluation&quot; sein, d.h. du holst die Werte aus der Map erst bei konkretem Zugriff (und dann evtl. zusätzlich noch mit einem Cache für weitere Zugriffe).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2381602</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2381602</guid><dc:creator><![CDATA[Th69]]></dc:creator><pubDate>Wed, 05 Feb 2014 10:31:57 GMT</pubDate></item><item><title><![CDATA[Reply to getName() für Attribut vom Typ Zeiger auf eigene Klasse on Fri, 07 Feb 2014 20:43:12 GMT]]></title><description><![CDATA[<p>Hallo Th69,</p>
<p>bitte entschuldige die späte Rückmeldung, ich war die letzten zwei Tage offline.</p>
<p>Vielen Dank für deine Antwort, die hat mir sehr geholfen. Z. B. lasse ich die Daten jetzt tatsächlich erstmal in der map und dass eine Referenz nicht NULL sein kann ist gut zu wissen (dachte, ich hätte das mal irgendwo gesehen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /> ).</p>
<p>Der Aufruf des string-Konstruktors in Zeile 30 war mir klar. Allerdings verstehe ich immer noch nicht, warum ich in Zeile 40 einen Error bekomme, in Zeile 35 aber &quot;nur&quot; eine Warnung.</p>
<p>Außerdem stehe ich jetzt wieder an einer anderen Stelle auf dem Schlauch. Ich bin mir ziemlich sicher, dass es heute Nachmittag noch funktioniert hat <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<p>Es geht um folgenden Code-Schnipsel:</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace std;

int main(){

    string line = &quot;Max Mustermann\t -   \tJane Doe  \t  \t&quot;;

    string nameA = line.substr(0, line.find_first_of('-') - 1);
    nameA = nameA.substr(nameA.find_first_not_of(&quot; \n\t\f\v\r&quot;), nameA.find_last_not_of(&quot; \n\t\f\v\r&quot;) + 1);

    string nameB = line.substr(line.find_first_of('-') + 1);
    nameB = nameB.substr(nameB.find_first_not_of(&quot; \n\t\f\v\r&quot;), nameB.find_last_not_of(&quot; \n\t\f\v\r&quot;) + 1);

    cout &lt;&lt; &quot;X&quot; &lt;&lt; nameA &lt;&lt; &quot;X   X&quot; &lt;&lt; nameB &lt;&lt; &quot;X&quot; &lt;&lt; endl;

    return 0;
}
</code></pre>
<p>Ich möchte am Ende in nameA &quot;Max Mustermann&quot; und in nameB &quot;Jane Doe&quot; stehen haben. Bei Max klappt das noch, aber bei Jane habe ich noch ein</p>
<pre><code>&quot;  \t &quot;
</code></pre>
<p>dahinter. Die Ausgabe ist also:</p>
<pre><code>XMax MustermannX   XJane Doe     X
statt
XMax MustermannX   XJane DoeX
</code></pre>
<p>Frage 1: Was mache ich falsch?<br />
Frage 2: Hätte ich für die Frage einen neuen Beitrag aufmachen sollen?</p>
<p>Vielen Dank für eure Hilfe und viele Grüße!<br />
Matze</p>
<p>PS: dieses mal antworte ich auch etwas schneller <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="🙂"
    /> <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2382118</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2382118</guid><dc:creator><![CDATA[MatzeHHC]]></dc:creator><pubDate>Fri, 07 Feb 2014 20:43:12 GMT</pubDate></item><item><title><![CDATA[Reply to getName() für Attribut vom Typ Zeiger auf eigene Klasse on Fri, 07 Feb 2014 21:09:33 GMT]]></title><description><![CDATA[<p>Habe jetzt gemerkt, dass es mit</p>
<pre><code>string nameB = line.substr(line.find_first_of('-') + 1);
nameB = nameB.substr(nameB.find_first_not_of(&quot; \n\t\f\v\r&quot;), nameB.find_last_not_of(&quot; \n\t\f\v\r&quot;) + 1);
nameB = nameB.substr(0, nameB.find_last_not_of(&quot; \n\t\f\v\r&quot;) + 1);
</code></pre>
<p>funktioniert. Dann ist es auch egal, wie viele '\t' am Ende standen. Aber verstehen kann ich das immer noch nicht. <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=":confused:"
      alt="😕"
    /><br />
Ich wäre für eine Erklärung sehr dankbar. Vielleicht ist es für mich einfach schon zu spät heute... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2382121</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2382121</guid><dc:creator><![CDATA[MatzeHHC]]></dc:creator><pubDate>Fri, 07 Feb 2014 21:09:33 GMT</pubDate></item><item><title><![CDATA[Reply to getName() für Attribut vom Typ Zeiger auf eigene Klasse on Fri, 07 Feb 2014 21:24:44 GMT]]></title><description><![CDATA[<p>Ok, ich habe es gefunden.<br />
Mann bin ich blöd <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f621.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--pouting_face"
      title=":rage:"
      alt="😡"
    /></p>
<p>substr() erwartet keinen Angaben nach dem Motto &quot;von, bis&quot;, sonder nach dem Motto &quot;von, wieviele&quot;. Hatte an das Äquivalen in Java gedacht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<p>Viele Grüße<br />
Matze</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2382122</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2382122</guid><dc:creator><![CDATA[MatzeHHC]]></dc:creator><pubDate>Fri, 07 Feb 2014 21:24:44 GMT</pubDate></item><item><title><![CDATA[Reply to getName() für Attribut vom Typ Zeiger auf eigene Klasse on Sat, 08 Feb 2014 11:11:30 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>bzgl.</p>
<blockquote>
<p>Der Aufruf des string-Konstruktors in Zeile 30 war mir klar. Allerdings verstehe ich immer noch nicht, warum ich in Zeile 40 einen Error bekomme, in Zeile 35 aber &quot;nur&quot; eine Warnung.</p>
</blockquote>
<p>Das liegt darin, daß bei std::string implizit der std::string(const char *)-Konstruktor aufgerufen wird (d.h. es wird ein lokales temporäres string-Objekt erstellt). Hierbei ist aber zu beachten, daß gerade dieser Fall (nämlich NULL zu übergeben) undefiniertes Verhalten ist (also laut Spezifikation nicht erlaubt ist, s.a. <a href="http://www.cplusplus.com/reference/string/string/string/" rel="nofollow">string::string</a> (unter &quot;Exception safety&quot;)).</p>
<p>Und bei der Klasse A gibt es eben keine implizite Konvertierung mittels eines Nullzeigers (bzw. der Zahl 0) und daher direkt einen Fehler. Kannst ja mal testweise bei KlasseA den Konstruktor KlasseA(int n) oder KlasseA(const void <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="😉"
    /> o.ä. hinzufügen (neu kompilieren und dann staunen ;-).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2382155</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2382155</guid><dc:creator><![CDATA[Th69]]></dc:creator><pubDate>Sat, 08 Feb 2014 11:11:30 GMT</pubDate></item><item><title><![CDATA[Reply to getName() für Attribut vom Typ Zeiger auf eigene Klasse on Sat, 08 Feb 2014 14:38:31 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>Th69 schrieb:</p>
<blockquote>
<p>Das liegt darin, daß bei std::string implizit der std::string(const char *)-Konstruktor aufgerufen wird (d.h. es wird ein lokales temporäres string-Objekt erstellt). Hierbei ist aber zu beachten, daß gerade dieser Fall (nämlich NULL zu übergeben) undefiniertes Verhalten ist (also laut Spezifikation nicht erlaubt ist, s.a. <a href="http://www.cplusplus.com/reference/string/string/string/" rel="nofollow">string::string</a> (unter &quot;Exception safety&quot;)).</p>
</blockquote>
<p>Ah ja, na klar! Ich hatte mir nur die ctor-Prototypen angeschaut und gar nicht bis &quot;Exception safety&quot; gelesen. Dass bei NULL der char*-Konstruktor aufegrufen werden könnte hatte ich gar nicht in Betracht gezogen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<p>Danke und Gruß!<br />
Matze</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2382176</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2382176</guid><dc:creator><![CDATA[MatzeHHC]]></dc:creator><pubDate>Sat, 08 Feb 2014 14:38:31 GMT</pubDate></item></channel></rss>