<?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[friend Funktionen anderer Klassen]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich beschäftige mich gerade mit C++ anhand eines Buches. Als Aufgabe am Ende eines Kapitels ist ein bestehendes Programm zu erweitern. Das Programm besteht aus einer verketteten Liste, in der Namen gespeichert werden können. Aufgabe ist es, ein Objekt in den Ausgabestream cout &lt;&lt; zu schreiben, bzw. einen Operator overload hierzu zu erstellen, der zur friend Funktion in einer anderen Klasse werden und dort ausgegeben werden soll. Als Beispiel ist der &lt;&lt; schon überladen, jedoch ausserhalb einer Klasse. Hier erstmal der Code (ich hoffe, er ist nicht zu lang, wusste aber nicht, wie ich ihn kürzen sollte, ohne den Zusammenhang zu verlieren):</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;

using namespace std;

class Player
{

public:  
    Player(const string&amp; name = &quot;&quot;);
    string GetName() const;
    Player* GetNext() const;
    void SetNext(Player* next);

    // Hinzu
    ostream&amp; Player::operator&lt;&lt;(ostream&amp; os, const Player&amp; p);

private:
    string m_Name;
    Player* m_pNext;  //Pointer to next player in list
};

// Overload hinzu
ostream&amp; Player::operator&lt;&lt;(ostream&amp; os, const Player&amp; p)
{
	os &lt;&lt; p.GetName();
	return os;
}

Player::Player(const string&amp; name): 
    m_Name(name), 
    m_pNext(0) 
{}

string Player::GetName() const
{
    return m_Name;
}

Player* Player::GetNext() const
{
    return m_pNext;
}

void Player::SetNext(Player* next)
{
    m_pNext = next;
}

class Lobby
{
    friend ostream&amp; operator&lt;&lt;(ostream&amp; os, const Lobby&amp; aLobby);

    // Hinzu
    friend ostream&amp; Player::operator&lt;&lt;(ostream&amp; os, const Player&amp; p);

public:
    Lobby();
    ~Lobby();
    void AddPlayer();
    void RemovePlayer();
    void Clear();

private:
    Player* m_pHead;  
};

Lobby::Lobby():
    m_pHead(0)
{}

Lobby::~Lobby()
{
    Clear();
}

void Lobby::AddPlayer()
{
    //create a new player node
    cout &lt;&lt; &quot;Please enter the name of the new player: &quot;;
    string name;
    cin &gt;&gt; name;
    Player* pNewPlayer = new Player(name);

    //if list is empty, make head of list this new player
    if (m_pHead == 0)
    {
        m_pHead = pNewPlayer;
    }

    //otherwise find the end of the list and add the player there
    else
    {
        Player* pIter = m_pHead;
        while (pIter-&gt;GetNext() != 0)
        {
            pIter = pIter-&gt;GetNext();       
        }
        pIter-&gt;SetNext(pNewPlayer);
    }

    // Hinzu
    // cout &lt;&lt; *pNewPlayer;
}

void Lobby::RemovePlayer()
{
    if (m_pHead == 0)
    {
        cout &lt;&lt; &quot;The game lobby is empty.  No one to remove!\n&quot;;
    }
    else
    {
        Player* pTemp = m_pHead;
        m_pHead = m_pHead-&gt;GetNext();
        delete pTemp;
    }
}

void Lobby::Clear()
{
    while (m_pHead != 0)
    {
        RemovePlayer();
    }
}

ostream&amp; operator&lt;&lt;(ostream&amp; os, const Lobby&amp; aLobby)
{
    Player* pIter = aLobby.m_pHead;
    os &lt;&lt; &quot;\nHere's who's in the game lobby:\n&quot;;
    if (pIter == 0)
    {
        os &lt;&lt; &quot;The lobby is empty.\n&quot;;
    }
    else
    {
        while (pIter != 0)
        {   
            os &lt;&lt; pIter-&gt;GetName() &lt;&lt; endl;
	        pIter = pIter-&gt;GetNext();
        }
    }
    return os;
}

int main()
{
    Lobby myLobby;
    int choice;
    do
    {
	cout &lt;&lt; myLobby;
        cout &lt;&lt; &quot;\nGAME LOBBY\n&quot;;
        cout &lt;&lt; &quot;0 - Exit the program.\n&quot;;
        cout &lt;&lt; &quot;1 - Add a player to the lobby.\n&quot;;
        cout &lt;&lt; &quot;2 - Remove a player from the lobby.\n&quot;;
        cout &lt;&lt; &quot;3 - Clear the lobby.\n&quot;;
        cout &lt;&lt; endl &lt;&lt; &quot;Enter choice: &quot;;
        cin &gt;&gt; choice;
        switch (choice)
        {
            case 0: cout &lt;&lt; &quot;Good-bye.\n&quot;; break;
            case 1: myLobby.AddPlayer(); break;  
            case 2: myLobby.RemovePlayer(); break;
            case 3: myLobby.Clear(); break;
            default: cout &lt;&lt; &quot;That was not a valid choice.\n&quot;;
        }
    }
    while (choice != 0);
    return 0;
}
</code></pre>
<p>Die Zeilen unter den Kommentaren //Hinzu habe ich hinzu gefügt. Jedoch erscheint dann folgende Meldung:</p>
<blockquote>
<p>game_lobby_exer1.cpp:18: error: extra qualification ‘Player::’ on member ‘operator&lt;&lt;’<br />
game_lobby_exer1.cpp:18: error: ‘std::ostream&amp; Player::operator&lt;&lt;(std::ostream&amp;, const Player&amp;)’ must take exactly one argument<br />
game_lobby_exer1.cpp:27: error: ‘std::ostream&amp; Player::operator&lt;&lt;(std::ostream&amp;, const Player&amp;)’ must take exactly one argument<br />
game_lobby_exer1.cpp:59: error: ‘std::ostream&amp; Player::operator&lt;&lt;(std::ostream&amp;, const Player&amp;)’ must take exactly one argument</p>
</blockquote>
<p>Wenn ich die Zeile</p>
<pre><code class="language-cpp">cout &lt;&lt; *pNewPlayer;
</code></pre>
<p>(Zeile 104) auskommentiere, hagelt es nur so von Fehlermeldungen. Ich wüsste aber nicht, wie ich an der Stelle eine Referenz des Objektes übergeben könnte, bzw. taucht auch die Frage auf; ist eine Referenz nur ein konstanter Zeigern, und kann er als solcher eingesetzt werden?</p>
<p>Danke für Antworten.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/263765/friend-funktionen-anderer-klassen</link><generator>RSS for Node</generator><lastBuildDate>Sat, 05 Sep 2026 13:44:46 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/263765.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 26 Mar 2010 09:24:25 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Fri, 26 Mar 2010 09:24:25 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich beschäftige mich gerade mit C++ anhand eines Buches. Als Aufgabe am Ende eines Kapitels ist ein bestehendes Programm zu erweitern. Das Programm besteht aus einer verketteten Liste, in der Namen gespeichert werden können. Aufgabe ist es, ein Objekt in den Ausgabestream cout &lt;&lt; zu schreiben, bzw. einen Operator overload hierzu zu erstellen, der zur friend Funktion in einer anderen Klasse werden und dort ausgegeben werden soll. Als Beispiel ist der &lt;&lt; schon überladen, jedoch ausserhalb einer Klasse. Hier erstmal der Code (ich hoffe, er ist nicht zu lang, wusste aber nicht, wie ich ihn kürzen sollte, ohne den Zusammenhang zu verlieren):</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;

using namespace std;

class Player
{

public:  
    Player(const string&amp; name = &quot;&quot;);
    string GetName() const;
    Player* GetNext() const;
    void SetNext(Player* next);

    // Hinzu
    ostream&amp; Player::operator&lt;&lt;(ostream&amp; os, const Player&amp; p);

private:
    string m_Name;
    Player* m_pNext;  //Pointer to next player in list
};

// Overload hinzu
ostream&amp; Player::operator&lt;&lt;(ostream&amp; os, const Player&amp; p)
{
	os &lt;&lt; p.GetName();
	return os;
}

Player::Player(const string&amp; name): 
    m_Name(name), 
    m_pNext(0) 
{}

string Player::GetName() const
{
    return m_Name;
}

Player* Player::GetNext() const
{
    return m_pNext;
}

void Player::SetNext(Player* next)
{
    m_pNext = next;
}

class Lobby
{
    friend ostream&amp; operator&lt;&lt;(ostream&amp; os, const Lobby&amp; aLobby);

    // Hinzu
    friend ostream&amp; Player::operator&lt;&lt;(ostream&amp; os, const Player&amp; p);

public:
    Lobby();
    ~Lobby();
    void AddPlayer();
    void RemovePlayer();
    void Clear();

private:
    Player* m_pHead;  
};

Lobby::Lobby():
    m_pHead(0)
{}

Lobby::~Lobby()
{
    Clear();
}

void Lobby::AddPlayer()
{
    //create a new player node
    cout &lt;&lt; &quot;Please enter the name of the new player: &quot;;
    string name;
    cin &gt;&gt; name;
    Player* pNewPlayer = new Player(name);

    //if list is empty, make head of list this new player
    if (m_pHead == 0)
    {
        m_pHead = pNewPlayer;
    }

    //otherwise find the end of the list and add the player there
    else
    {
        Player* pIter = m_pHead;
        while (pIter-&gt;GetNext() != 0)
        {
            pIter = pIter-&gt;GetNext();       
        }
        pIter-&gt;SetNext(pNewPlayer);
    }

    // Hinzu
    // cout &lt;&lt; *pNewPlayer;
}

void Lobby::RemovePlayer()
{
    if (m_pHead == 0)
    {
        cout &lt;&lt; &quot;The game lobby is empty.  No one to remove!\n&quot;;
    }
    else
    {
        Player* pTemp = m_pHead;
        m_pHead = m_pHead-&gt;GetNext();
        delete pTemp;
    }
}

void Lobby::Clear()
{
    while (m_pHead != 0)
    {
        RemovePlayer();
    }
}

ostream&amp; operator&lt;&lt;(ostream&amp; os, const Lobby&amp; aLobby)
{
    Player* pIter = aLobby.m_pHead;
    os &lt;&lt; &quot;\nHere's who's in the game lobby:\n&quot;;
    if (pIter == 0)
    {
        os &lt;&lt; &quot;The lobby is empty.\n&quot;;
    }
    else
    {
        while (pIter != 0)
        {   
            os &lt;&lt; pIter-&gt;GetName() &lt;&lt; endl;
	        pIter = pIter-&gt;GetNext();
        }
    }
    return os;
}

int main()
{
    Lobby myLobby;
    int choice;
    do
    {
	cout &lt;&lt; myLobby;
        cout &lt;&lt; &quot;\nGAME LOBBY\n&quot;;
        cout &lt;&lt; &quot;0 - Exit the program.\n&quot;;
        cout &lt;&lt; &quot;1 - Add a player to the lobby.\n&quot;;
        cout &lt;&lt; &quot;2 - Remove a player from the lobby.\n&quot;;
        cout &lt;&lt; &quot;3 - Clear the lobby.\n&quot;;
        cout &lt;&lt; endl &lt;&lt; &quot;Enter choice: &quot;;
        cin &gt;&gt; choice;
        switch (choice)
        {
            case 0: cout &lt;&lt; &quot;Good-bye.\n&quot;; break;
            case 1: myLobby.AddPlayer(); break;  
            case 2: myLobby.RemovePlayer(); break;
            case 3: myLobby.Clear(); break;
            default: cout &lt;&lt; &quot;That was not a valid choice.\n&quot;;
        }
    }
    while (choice != 0);
    return 0;
}
</code></pre>
<p>Die Zeilen unter den Kommentaren //Hinzu habe ich hinzu gefügt. Jedoch erscheint dann folgende Meldung:</p>
<blockquote>
<p>game_lobby_exer1.cpp:18: error: extra qualification ‘Player::’ on member ‘operator&lt;&lt;’<br />
game_lobby_exer1.cpp:18: error: ‘std::ostream&amp; Player::operator&lt;&lt;(std::ostream&amp;, const Player&amp;)’ must take exactly one argument<br />
game_lobby_exer1.cpp:27: error: ‘std::ostream&amp; Player::operator&lt;&lt;(std::ostream&amp;, const Player&amp;)’ must take exactly one argument<br />
game_lobby_exer1.cpp:59: error: ‘std::ostream&amp; Player::operator&lt;&lt;(std::ostream&amp;, const Player&amp;)’ must take exactly one argument</p>
</blockquote>
<p>Wenn ich die Zeile</p>
<pre><code class="language-cpp">cout &lt;&lt; *pNewPlayer;
</code></pre>
<p>(Zeile 104) auskommentiere, hagelt es nur so von Fehlermeldungen. Ich wüsste aber nicht, wie ich an der Stelle eine Referenz des Objektes übergeben könnte, bzw. taucht auch die Frage auf; ist eine Referenz nur ein konstanter Zeigern, und kann er als solcher eingesetzt werden?</p>
<p>Danke für Antworten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874062</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874062</guid><dc:creator><![CDATA[TestGuest]]></dc:creator><pubDate>Fri, 26 Mar 2010 09:24:25 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Fri, 26 Mar 2010 09:32:34 GMT]]></title><description><![CDATA[<p>Die Stream-Operatoren dürfen nicht Member der Klasse sein, deren Ein-/Ausgabe sie implementieren sollen, weil die jeweilige Klasseninstanz im zweiten Parameter übergeben werden muss. Wenn du aus den Operatoren Klassenmember machst, wird die Klasseninstanz implizit als erster Parameter übergeben. Darum ist dann auch nur noch ein Parameter notwenig - aber die Reihenfolge passt dann natürlich nicht.</p>
<p>Das mit friend und außerhalb ist also keine Laune, sondern Absicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874065</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874065</guid><dc:creator><![CDATA[MFK]]></dc:creator><pubDate>Fri, 26 Mar 2010 09:32:34 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Fri, 26 Mar 2010 09:44:24 GMT]]></title><description><![CDATA[<p>MFK schrieb:</p>
<blockquote>
<p>Die Stream-Operatoren dürfen nicht Member der Klasse sein, deren Ein-/Ausgabe sie implementieren sollen, weil die jeweilige Klasseninstanz im zweiten Parameter übergeben werden muss. Wenn du aus den Operatoren Klassenmember machst, wird die Klasseninstanz implizit als erster Parameter übergeben. Darum ist dann auch nur noch ein Parameter notwenig - aber die Reihenfolge passt dann natürlich nicht.</p>
<p>Das mit friend und außerhalb ist also keine Laune, sondern Absicht.</p>
</blockquote>
<p>Erstmal danke für die schnelle Antwort. Die Aufgabe besteht jedoch darin, die Überladung von &lt;&lt; innerhalb der Klasse Player zu implementieren und diese dann in Lobby zur friend Funktion zu machen. Bei einer &quot;normalen&quot; Funktion ist das mit dem impliziten Parameter der Instanz schon klar, da würde ja dann auch *pNewPlayer-&gt;anyprintfunction() ohne Parameter ausreichen. Aber in dem Fall, dass ich direkt &quot;cout &lt;&lt; playerobj&quot; implementieren will, muss ich doch eine Referenz auf playerobj haben, ebenso auf einen Stream auf der rechten Seite?! Lässt sich das also garnicht implementieren?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874071</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874071</guid><dc:creator><![CDATA[TestGuest]]></dc:creator><pubDate>Fri, 26 Mar 2010 09:44:24 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Fri, 26 Mar 2010 10:11:24 GMT]]></title><description><![CDATA[<p>TestGuest schrieb:</p>
<blockquote>
<p>Aber in dem Fall, dass ich direkt &quot;cout &lt;&lt; playerobj&quot; implementieren will, muss ich doch eine Referenz auf playerobj haben, ebenso auf einen Stream auf der rechten Seite?!</p>
</blockquote>
<p>Du brauchst den Stream auf der linken Seite. Ich sag's auch gern nochmal: Die Stream-Operatoren dürfen nicht Member der Klasse sein, deren Ein-/Ausgabe sie implementieren sollen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874080</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874080</guid><dc:creator><![CDATA[MFK]]></dc:creator><pubDate>Fri, 26 Mar 2010 10:11:24 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Fri, 26 Mar 2010 10:17:23 GMT]]></title><description><![CDATA[<p>TestGuest schrieb:</p>
<blockquote>
<p>Erstmal danke für die schnelle Antwort. Die Aufgabe besteht jedoch darin, die Überladung von &lt;&lt; innerhalb der Klasse Player zu implementieren und diese dann in Lobby zur friend Funktion zu machen. Bei einer &quot;normalen&quot; Funktion ist das mit dem impliziten Parameter der Instanz schon klar, da würde ja dann auch *pNewPlayer-&gt;anyprintfunction() ohne Parameter ausreichen. Aber in dem Fall, dass ich direkt &quot;cout &lt;&lt; playerobj&quot; implementieren will, muss ich doch eine Referenz auf playerobj haben, ebenso auf einen Stream auf der rechten Seite?! Lässt sich das also garnicht implementieren?</p>
</blockquote>
<p>Nein, bei cout &lt;&lt; playerobj ist der Stream das linke Argument, man könnte es daher höchstenns als Member von std::ostream implementieren. Das ist aber natürlich nicht möglich, also muss es eine freie Fuktion sein. Zeig uns mal den Text der Aufgabe, vielleicht hast du da was missverstanden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874084</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874084</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Fri, 26 Mar 2010 10:17:23 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Fri, 26 Mar 2010 12:16:41 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>Nein, bei cout &lt;&lt; playerobj ist der Stream das linke Argument, man könnte es daher höchstenns als Member von std::ostream implementieren. Das ist aber natürlich nicht möglich, also muss es eine freie Fuktion sein. Zeig uns mal den Text der Aufgabe, vielleicht hast du da was missverstanden.</p>
</blockquote>
<p>Ok, muss ich abtippen:</p>
<blockquote>
<p>Improve the <em>Lobby</em> class from the Game Lobby program by writing a friend function of the <em>Player</em> class that allows a <em>Player</em> object to be sent to <em>cout</em>. Next, update the function that allows a <em>Lobby</em> object to be sent to <em>cout</em> so that it uses your new function for sending a <em>Player</em> object to <em>cout</em>.</p>
</blockquote>
<p>Übrigens, in einem anderen Beispiel wurde der &quot;=&quot; Operator auch als Member überladen, hier mal der entsprechende Ausschnitt:</p>
<pre><code class="language-cpp">class Critter
{

public: 

    Critter(const string&amp; name = &quot;&quot;, int age = 0);  
    ~Critter();                   //destructor prototype   
    Critter(const Critter&amp; c);    //copy constructor prototype
    Critter&amp; Critter::operator=(const Critter&amp; c);  //overloaded assignment op
    void Greet() const;

private:
    string* m_pName;
    int m_Age;
};

....

Critter&amp; Critter::operator=(const Critter&amp; c)  //overloaded assignment op def
{
    cout &lt;&lt; &quot;Overloaded Assignment Operator called\n&quot;;
    if (this != &amp;c)
    {
        delete m_pName;
        m_pName = new string(*(c.m_pName));
        m_Age = c.m_Age;
    }
    return *this;
}
</code></pre>
<p>Im Prinzip ist das doch das Gleiche, oder?</p>
<p>PS: Wenn man Code mit copy&amp;paste einfügt, wird er nach der ersten Vorschau mit vielen Leerzeilen versehen. Wie verhindert man das? Mein Editor ist gedit.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874143</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874143</guid><dc:creator><![CDATA[TestGuest]]></dc:creator><pubDate>Fri, 26 Mar 2010 12:16:41 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Fri, 26 Mar 2010 12:24:51 GMT]]></title><description><![CDATA[<p>TestGuest schrieb:</p>
<blockquote>
<blockquote>
<p>Improve the <em>Lobby</em> class from the Game Lobby program by writing a friend function of the <em>Player</em> class that allows a <em>Player</em> object to be sent to <em>cout</em>.</p>
</blockquote>
</blockquote>
<p>Da steht nichts davon, dass du Player eine Methode hinzufügen sollst, sondern dass du eine friend-Funktion der Klasse schreiben sollst. Ein friend ist kein Member.</p>
<p>TestGuest schrieb:</p>
<blockquote>
<p>Übrigens, in einem anderen Beispiel wurde der &quot;=&quot; Operator auch als Member überladen, hier mal der entsprechende Ausschnitt:<br />
...<br />
Im Prinzip ist das doch das Gleiche, oder?</p>
</blockquote>
<p>Nein, weil beim Zuweisungsoperator deine Klasseninstanz auf der <em>linken</em> Seite steht.<br />
Manche Operatoren müssen Member sein, manche muss man als freie Funktionen anlegen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874147</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874147</guid><dc:creator><![CDATA[MFK]]></dc:creator><pubDate>Fri, 26 Mar 2010 12:24:51 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Fri, 26 Mar 2010 12:25:55 GMT]]></title><description><![CDATA[<blockquote>
<p>Improve the <em>Lobby</em> class from the Game Lobby program by <strong>writing a friend function of the <em>Player</em> class that allows a <em>Player</em> object to be sent to <em>cout</em>.</strong> Next, update the function that allows a <em>Lobby</em> object to be sent to <em>cout</em> so that it uses your new function for sending a <em>Player</em> object to <em>cout</em>.</p>
</blockquote>
<p>Steht doch gar nicht drinnen, dass das ne Member-Funktion sein soll.<br />
Zur Info: Zum Interface einer Klasse gehören auch freie Funktionen, die auf der jeweiligen Klasse arbeiten! Somit ist auch eine freie Funktionen ein &quot;improvement&quot; deiner Klasse.</p>
<p>TestGuest schrieb:</p>
<blockquote>
<p>PS: Wenn man Code mit copy&amp;paste einfügt, wird er nach der ersten Vorschau mit vielen Leerzeilen versehen. Wie verhindert man das? Mein Editor ist gedit.</p>
</blockquote>
<p>Das liegt an der Editorkomonente die dein Browser verwendet. Du hast wahrscheinlich da Tabs im Code. Die werden beim Pasten in Leerzeichen umgewandelt. Und die Editorkomponente wird da wohl gaaanz viele reinbauen (8 Stück, kann das sein?).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874148</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874148</guid><dc:creator><![CDATA[l&#x27;abra d&#x27;or]]></dc:creator><pubDate>Fri, 26 Mar 2010 12:25:55 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Fri, 26 Mar 2010 12:59:56 GMT]]></title><description><![CDATA[<p>Erstmal danke an Alle! Das heisst also, dass die Überladung ausserhalb der Klassendefinition und fast ebenso wie die Überladung fürs Lobby Objekt implementiert wird. Hier die entsprechenden Codefragmente:</p>
<pre><code class="language-cpp">class Lobby
{
    friend ostream&amp; operator&lt;&lt;(ostream&amp; os, const Lobby&amp; aLobby);

    // Hinzu
    friend ostream&amp; operator&lt;&lt;(ostream&amp; os, const Player&amp; p);
...

};

// Hinzu
ostream&amp; operator&lt;&lt;(ostream&amp; os, const Player&amp; p)
{
    os &lt;&lt; p.GetName();
    return os;
}

void Lobby::AddPlayer()
{
    //create a new player node
    cout &lt;&lt; &quot;Please enter the name of the new player: &quot;;
    string name;
    cin &gt;&gt; name;
    Player* pNewPlayer = new Player(name);

    ...

    cout &lt;&lt; pNewPlayer;
    // cout &lt;&lt; *pNewPlayer;
}
</code></pre>
<p>Bei den letzten Zeilen bekomme ich nun im ersten Fall (28) lediglich die Adresse des Objektes, im zweiten Fall (29) wieder eine Reihe von Fehlermeldungen. Ich hätte gedacht, dass die erste Zeile funktionieren muss, da doch eine Referenz auch nur ein Zeiger auf ein Objekt ist?!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874169</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874169</guid><dc:creator><![CDATA[TestGuest]]></dc:creator><pubDate>Fri, 26 Mar 2010 12:59:56 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Fri, 26 Mar 2010 13:05:03 GMT]]></title><description><![CDATA[<p>Die Funktion muss ein Friend von Player sein, nicht von Lobby. Mit Lobby hat sie nichts am Hut.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874173</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874173</guid><dc:creator><![CDATA[MFK]]></dc:creator><pubDate>Fri, 26 Mar 2010 13:05:03 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Fri, 26 Mar 2010 13:15:58 GMT]]></title><description><![CDATA[<p>MFK schrieb:</p>
<blockquote>
<p>Die Funktion muss ein Friend von Player sein, nicht von Lobby. Mit Lobby hat sie nichts am Hut.</p>
</blockquote>
<p>Oh natürlich! Das fällt nun unter die Rubrik Flüchtigkeitsfehler. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /><br />
So funktioniert es jetzt, jedoch mit:</p>
<pre><code class="language-cpp">cout &lt;&lt; *pNewPlayer;
</code></pre>
<p>Klar, dass der Zeigerinhalt die Referenz auf das Objekt darstellt. Aber die ist doch auch nur ein Zeiger, oder? Also wäre der Zeiger pNewPlayer ein Zeiger auf einen Zeiger, richtig?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874178</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874178</guid><dc:creator><![CDATA[TestGuest]]></dc:creator><pubDate>Fri, 26 Mar 2010 13:15:58 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Fri, 26 Mar 2010 13:34:40 GMT]]></title><description><![CDATA[<p>TestGuest schrieb:</p>
<blockquote>
<p>Klar, dass der Zeigerinhalt die Referenz auf das Objekt darstellt. Aber die ist doch auch nur ein Zeiger, oder? Also wäre der Zeiger pNewPlayer ein Zeiger auf einen Zeiger, richtig?</p>
</blockquote>
<p>Lös dich bitte von der Vorstellung, dass eine Referenz &quot;auch nur ein Zeiger&quot; ist. Es stimmt einfach nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874191</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874191</guid><dc:creator><![CDATA[MFK]]></dc:creator><pubDate>Fri, 26 Mar 2010 13:34:40 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Fri, 26 Mar 2010 14:57:58 GMT]]></title><description><![CDATA[<p>MFK schrieb:</p>
<blockquote>
<p>Lös dich bitte von der Vorstellung, dass eine Referenz &quot;auch nur ein Zeiger&quot; ist. Es stimmt einfach nicht.</p>
</blockquote>
<p>Ok, dann nehme ich das so hin. Kannst Du den Unterschied illustrieren? Weder in dem Buch, noch in Tutorials wird mir richtig klar, wo der Unterschied liegt, bzw. inwieweit beides austauschbar ist (also, kann man z.B. einen Zeiger übergeben, wo eine Referenz verlangt wird, usw.)?!</p>
<p>Ich habe auch Probleme mit den Konventionen von Zeigern. Im Buch steht folgendes:</p>
<pre><code>int score = 100;
int* const pScore = &amp;score;
</code></pre>
<p>ist ein Konstanter Zeiger. Weiterhin</p>
<pre><code>const int* pNumber = &amp;score;
</code></pre>
<p>ist ein Zeiger auf eine Konstante. Und dann gibt es halt noch konstante Zeiger auf eine Konstante. In einem Tutorial hier aus dem Forum (nämlich aus cpp_mta_rwthaa.pdf) ist:</p>
<pre><code>char const *p:
</code></pre>
<p>ein Zeiger auf eine Konstante, und:</p>
<pre><code>char w;
char * const p = w;
</code></pre>
<p>ein konstanter Zeiger. Gibt es eine Fausregel, wie man sich die unterschiedlichen Schreibweisen einprägen kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874222</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874222</guid><dc:creator><![CDATA[TestGuest]]></dc:creator><pubDate>Fri, 26 Mar 2010 14:57:58 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Sun, 28 Mar 2010 05:32:58 GMT]]></title><description><![CDATA[<p>TestGuest schrieb:</p>
<blockquote>
<p>Kannst Du den Unterschied illustrieren? Weder in dem Buch, noch in Tutorials wird mir richtig klar, wo der Unterschied liegt, bzw. inwieweit beides austauschbar ist (also, kann man z.B. einen Zeiger übergeben, wo eine Referenz verlangt wird, usw.)?!</p>
</blockquote>
<p>Austauschbar sind also nicht Zeiger und Referenz, sondern Referenz und Objekt. Zeiger sind etwas komplett anderes.</p>
<p>Ein Zeiger ist ein eigenständiges Objekt, das einen Verweis auf ein anderes Objekt speichern kann (aber nicht muss). Auf welches Objekt ein Zeiger verweist, kann man ändern (daher die Unterscheidung zwischen konstantem Zeiger und Zeiger auf Konstante). Ein Zeiger kann Null sein, also auf nichts zeigen. Einen Zeiger behandelst du grundsätzlich anders als das Objekt, auf das es zeigt: Wenn du ihn übergeben willst, wo Objekt oder Referenz verlangt sind, musst du ihn dereferenzieren, um auf die Member zuzugreifen, brauchst du -&gt; statt . usw.</p>
<p>Eine Referenz ist ein neuer Name für ein bestehendes Objekt. Wenn du ein Objekt A hast und eine Referenz B dafür anlegst, sagst du dem Compiler: &quot;Wann immer ich jetzt B sage, meine ich Objekt A&quot;. Die Referenz ist also insofern kein eigenständiges Objekt, als du sie nicht beeinflussen kannst. Alles, was du mit der Referenz machst, machst du mit dem Objekt, für das sie steht. Weder kann eine Referenz auf ein anderes Objekt &quot;umgebogen&quot; werden, noch kann sie auf nichts zeigen (es sei denn, die Referenz lebt länger als das Objekt, für das sie steht, aber das ist ein Programmierfehler). Du behandelst eine Referenz im Code genauso wie das eigentliche Objekt.</p>
<p>TestGuest schrieb:</p>
<blockquote>
<p>Ich habe auch Probleme mit den Konventionen von Zeigern.</p>
</blockquote>
<p>Einfache Faustregel: Das const bezieht sich immer auf das, was links davon steht. Wenn das const ganz links steht, bezieht es sich auf das, was rechts davon steht. Folgende Deklarationen sind also gleichwertig:</p>
<pre><code class="language-cpp">const int* p;
int const* p;
</code></pre>
<p>Und ob du vor oder nach dem Stern Leerzeichen machst, ist inhaltlich völlig egal.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874370</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874370</guid><dc:creator><![CDATA[MFK]]></dc:creator><pubDate>Sun, 28 Mar 2010 05:32:58 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Sun, 28 Mar 2010 08:56:54 GMT]]></title><description><![CDATA[<p>MFK schrieb:</p>
<blockquote>
<p>Austauschbar sind also nicht Zeiger und Referenz, sondern Referenz und Objekt. Zeiger sind etwas komplett anderes.</p>
</blockquote>
<p>Ich wollte ein entsprechends Beispiel suchen, habe aber festgestellt, dass ich Referenzoperator (string&amp; obj) und Adressoperator (int* a = &amp;b) verwechselt hatte.</p>
<p>MFK schrieb:</p>
<blockquote>
<p>Wenn du ihn übergeben willst, wo Objekt oder Referenz verlangt sind, musst du ihn dereferenzieren, um auf die Member zuzugreifen, brauchst du -&gt; statt . usw.</p>
</blockquote>
<p>Das ist klar, oder auch (*pointer).member</p>
<p>MFK schrieb:</p>
<blockquote>
<p>Einfache Faustregel: Das const bezieht sich immer auf das, was links davon steht. Wenn das const ganz links steht, bezieht es sich auf das, was rechts davon steht. Folgende Deklarationen sind also gleichwertig:</p>
<pre><code class="language-cpp">const int* p;
int const* p;
</code></pre>
<p>Und ob du vor oder nach dem Stern Leerzeichen machst, ist inhaltlich völlig egal.</p>
</blockquote>
<p>Folgendes Zeilen sind laut Buch unterschiedlich:</p>
<pre><code class="language-cpp">int* const p = &amp;i;
const int* p;
const int* const p = &amp;i;
</code></pre>
<p>Im ersten Fall sollt es sich um einen konstanten Zeiger handeln, im zweiten Fall um einen Zeiger auf eine Konstante, letzteres ein konstanter Zeiger auf eine Konstante. Nach Deiner Erklärung würde sich also das const immer auf int* beziehen, im letzten Fall sogar doppelt. Das habe ich nicht verstanden.</p>
<p>PS: Was war denn mit dem Forum los?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874385</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874385</guid><dc:creator><![CDATA[TestGuest]]></dc:creator><pubDate>Sun, 28 Mar 2010 08:56:54 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Sun, 28 Mar 2010 09:30:36 GMT]]></title><description><![CDATA[<p>TestGuest schrieb:</p>
<blockquote>
<p>Nach Deiner Erklärung würde sich also das const immer auf int* beziehen, im letzten Fall sogar doppelt. Das habe ich nicht verstanden.</p>
</blockquote>
<p>Das const bezieht sich niemals auf int*. Du musst int und * getrennt betrachten. Du kannst das const auch dazwischen schreiben:</p>
<pre><code class="language-cpp">int* const p = &amp;i;       // const bezieht sich auf *
const int* p;            // const bezieht sich auf int
int const* p;            // const bezieht sich auf int
const int* const p = &amp;i; // ein const für int, eins für *
int const * const p = &amp;i;// ein const für int, eins für *
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1874390</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874390</guid><dc:creator><![CDATA[MFK]]></dc:creator><pubDate>Sun, 28 Mar 2010 09:30:36 GMT</pubDate></item><item><title><![CDATA[Reply to friend Funktionen anderer Klassen on Sun, 28 Mar 2010 11:26:27 GMT]]></title><description><![CDATA[<p>MFK schrieb:</p>
<blockquote>
<p>Das const bezieht sich niemals auf int*. Du musst int und * getrennt betrachten. Du kannst das const auch dazwischen schreiben:</p>
<pre><code class="language-cpp">int* const p = &amp;i;       // const bezieht sich auf *
const int* p;            // const bezieht sich auf int
int const* p;            // const bezieht sich auf int
const int* const p = &amp;i; // ein const für int, eins für *
int const * const p = &amp;i;// ein const für int, eins für *
</code></pre>
</blockquote>
<p>Vielen Dank, das ist so absolut verständlich! Bei der Gelegenheit hab ich mich gerade mal offiziell angemeldet.</p>
<p>Schönen Gruß</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1874458</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1874458</guid><dc:creator><![CDATA[wollewausfander]]></dc:creator><pubDate>Sun, 28 Mar 2010 11:26:27 GMT</pubDate></item></channel></rss>