<?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[Copy-Konstruktor und Operatoren&#x2F;Methoden]]></title><description><![CDATA[<p>So,<br />
nachdem das vorhin so gut und schnell mit der Hilfe geklappt hat, stehe ich jetzt wieder vor einem Problem:</p>
<p>Ich hab einen Copy-Konstruktor für meine Matrizen-Klasse gebastelt und eine Methode zum Addieren von Matrizen/ &quot;+&quot;-Operator überladen.<br />
Operator und Methode haben beide Matrix als Rückgabe-Typ.<br />
Nun dachte ich mir ich kann mit dem Copy-Konstruktor eine neues Objekt erstellen indem ich die aus der Addition resultierende Matrix übergebe ... geht natürlih nicht. Wenn ich aber eine vorher &quot;normal&quot; instanierte Matrix übergebe schluckt der Copy-Konstrukter die und abeitet normal.</p>
<pre><code class="language-cpp">...
class Matrix
{
    private:
    double** a;
    int Zeilen;
    int Spalten;

    public:
    Matrix (int, int, char, double);
    Matrix (Matrix&amp;);
    ~Matrix ();
    Matrix Addition (Matrix&amp;);
    Matrix operator + (Matrix&amp;);
    void ZeilenTausch (int, int);
    void SpaltenTausch (int, int);
    void Ausgabe();
};
...
Matrix :: Matrix (Matrix&amp; A) : Zeilen(A.Zeilen), Spalten(A.Spalten)
{
    a = new double* [A.Zeilen];
    for (int i=0; i&lt;A.Zeilen; i++)
    {
        a[i] = new double [A.Spalten];

        for (int j=0; j&lt;A.Spalten; j++)
        {
            a[i][j] = A.a[i][j];
        }
    }
    cout &lt;&lt; &quot;\n Copy-Konstruktor\n&quot;;
}
...
int main ()
{
Matrix A(4,4);
Matrix B(A); //geht wunderbar
Matrix C(A.Addition(B)); //will er nicht
Matrix D(A+B); //auch nicht
</code></pre>
<p>error: no matching function for call to `Matrix::Matrix(Matrix)'|<br />
note: candidates are: Matrix::Matrix(Matrix&amp;)|</p>
<p>Ich steh also mal wieder auf dem Schlauch und hoffe ihr könnt mir nochmal helfen.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/243591/copy-konstruktor-und-operatoren-methoden</link><generator>RSS for Node</generator><lastBuildDate>Sat, 19 Sep 2026 22:19:05 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/243591.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 18 Jun 2009 16:50:13 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Copy-Konstruktor und Operatoren&#x2F;Methoden on Thu, 18 Jun 2009 16:50:13 GMT]]></title><description><![CDATA[<p>So,<br />
nachdem das vorhin so gut und schnell mit der Hilfe geklappt hat, stehe ich jetzt wieder vor einem Problem:</p>
<p>Ich hab einen Copy-Konstruktor für meine Matrizen-Klasse gebastelt und eine Methode zum Addieren von Matrizen/ &quot;+&quot;-Operator überladen.<br />
Operator und Methode haben beide Matrix als Rückgabe-Typ.<br />
Nun dachte ich mir ich kann mit dem Copy-Konstruktor eine neues Objekt erstellen indem ich die aus der Addition resultierende Matrix übergebe ... geht natürlih nicht. Wenn ich aber eine vorher &quot;normal&quot; instanierte Matrix übergebe schluckt der Copy-Konstrukter die und abeitet normal.</p>
<pre><code class="language-cpp">...
class Matrix
{
    private:
    double** a;
    int Zeilen;
    int Spalten;

    public:
    Matrix (int, int, char, double);
    Matrix (Matrix&amp;);
    ~Matrix ();
    Matrix Addition (Matrix&amp;);
    Matrix operator + (Matrix&amp;);
    void ZeilenTausch (int, int);
    void SpaltenTausch (int, int);
    void Ausgabe();
};
...
Matrix :: Matrix (Matrix&amp; A) : Zeilen(A.Zeilen), Spalten(A.Spalten)
{
    a = new double* [A.Zeilen];
    for (int i=0; i&lt;A.Zeilen; i++)
    {
        a[i] = new double [A.Spalten];

        for (int j=0; j&lt;A.Spalten; j++)
        {
            a[i][j] = A.a[i][j];
        }
    }
    cout &lt;&lt; &quot;\n Copy-Konstruktor\n&quot;;
}
...
int main ()
{
Matrix A(4,4);
Matrix B(A); //geht wunderbar
Matrix C(A.Addition(B)); //will er nicht
Matrix D(A+B); //auch nicht
</code></pre>
<p>error: no matching function for call to `Matrix::Matrix(Matrix)'|<br />
note: candidates are: Matrix::Matrix(Matrix&amp;)|</p>
<p>Ich steh also mal wieder auf dem Schlauch und hoffe ihr könnt mir nochmal helfen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1728961</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1728961</guid><dc:creator><![CDATA[schmitzlipp]]></dc:creator><pubDate>Thu, 18 Jun 2009 16:50:13 GMT</pubDate></item><item><title><![CDATA[Reply to Copy-Konstruktor und Operatoren&#x2F;Methoden on Thu, 18 Jun 2009 16:58:00 GMT]]></title><description><![CDATA[<p>schmitzlipp schrieb:</p>
<blockquote>
<p>erstellen indem ich die aus der Addition resultierende Matrix übergebe ... geht natürlih nicht.</p>
</blockquote>
<p>Doch, das geht schon. Aber du bist einige Dinge falsch angegangen:</p>
<p><strong>1.</strong> Dein Kopierkonstruktor sollte keine Referenz nehmen, sondern eine Const-Referenz ( <code>const Matrix&amp;</code> ). Dies aus zwei Gründen: Erstens veränderst du die übergebene Matrix nicht. Zweitens kann man auf diese Weise auch temporäre Objekte übergeben.</p>
<p><strong>2.</strong> <code>Matrix Addition(Matrix&amp;)</code> : Mach das bitte nicht in C++. In Java macht man das z.B. so aufgrund mangelnder freier Funktionen. Hier hast du diese aber zur Verfügung, nutze sie also. Es muss nicht alles zur Klasse gehören.</p>
<p><strong>3.</strong> Gleiches gilt für den <code>operator+</code> . Mach diesen global und biete in der Klasse einen <code>operator+=</code> an. So kannst du das globale + auf die Memberfunktion <code>operator+=</code> zugreifen lassen, ohne dass du <code>friend</code> oder ähnliches benutzt. Ausserdem lässt das implizite Konvertierungen des ersten Operanden zu.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1728965</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1728965</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 18 Jun 2009 16:58:00 GMT</pubDate></item><item><title><![CDATA[Reply to Copy-Konstruktor und Operatoren&#x2F;Methoden on Thu, 18 Jun 2009 17:18:26 GMT]]></title><description><![CDATA[<p>Ok, vielen Dank für die Tipps.</p>
<p>Ich muss euch hiernochmal loben, hier wird einem promt geholfen und man wird nicht gleich zu Beginn blöd angemacht von wegen wie dumm man doch sei und so.<br />
Echt gute Community!!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1728977</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1728977</guid><dc:creator><![CDATA[schmitzlipp]]></dc:creator><pubDate>Thu, 18 Jun 2009 17:18:26 GMT</pubDate></item><item><title><![CDATA[Reply to Copy-Konstruktor und Operatoren&#x2F;Methoden on Thu, 18 Jun 2009 17:52:56 GMT]]></title><description><![CDATA[<p>du kansnt auch mal bei den artikeln vorbeischauen - dort gibts auch 3 wunderbare artike über operatorüberladungen..</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1728996</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1728996</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Thu, 18 Jun 2009 17:52:56 GMT</pubDate></item><item><title><![CDATA[Reply to Copy-Konstruktor und Operatoren&#x2F;Methoden on Thu, 18 Jun 2009 18:38:47 GMT]]></title><description><![CDATA[<p>schmitzlipp schrieb:</p>
<blockquote>
<p>Ich steh also mal wieder auf dem Schlauch und hoffe ihr könnt mir nochmal helfen.</p>
</blockquote>
<p>Du kannst Dir diesen ganzen Hickhack (eigener Copy-Ctor, Destructor und Assignment) für die Resourcen-Verwaltung (hier: der reservierte Speicher für die Elemente) gänzlich sparen, indem Du einen std::vector verwendest.</p>
<pre><code class="language-cpp">class Matrix
{
  private:
    std::vector&lt;double&gt; elemente;
    int Zeilen;
    int Spalten;

    inline int index(int i, int j)
    {return i+j*Zeilen;} // oder j+i*Spalten, wie Du willst

  public:
    Matrix (int z, int s, double v)
    : elemente(z*s,v),
      Zeilen(z),
      Spalten(s) {}

    double   operator()(int i, int j) const
    {return elemente.at(index(i,j));}

    double &amp; operator()(int i, int j)
    {return elemente.at(index(i,j));}

    Matrix&amp; operator+=(Matrix const&amp;);

    void ZeilenTausch (int, int);
    void SpaltenTausch (int, int);
};

Matrix&amp; Matrix::operator+=(Matrix const&amp; m)
{
  if (Zeilen!=m.Zeilen || Spalten!=m.Spalten) throw .....
  .....
  return *this;
}

.....

Matrix operator+(Matrix const&amp; lhs, Matrix const&amp; rhs)
{
  Matrix result = lhs;
  lhs += rhs;
  return result;
}
</code></pre>
<p>Man beachte: Die vom Compiler automatisch generierten Elementfunktionen (copy-ctor, assignment, destructor) machen genau das Richtige. Statt &quot;void Ausgabe&quot; habe ich einfach mal zwei Elementfunktionen hinzugefügt, die einem den Zugriff auf die Elemente erlauben.</p>
<p>Man kann diese Sache noch beliebig kompliziert werden lassen (siehe &quot;Boost.uBLAS&quot; Bibliothek <a href="http://www.boost.org/doc/libs/1_35_0/libs/numeric/ublas/doc/index.htm" rel="nofollow">http://www.boost.org/doc/libs/1_35_0/libs/numeric/ublas/doc/index.htm</a>).</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1729024</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1729024</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Thu, 18 Jun 2009 18:38:47 GMT</pubDate></item><item><title><![CDATA[Reply to Copy-Konstruktor und Operatoren&#x2F;Methoden on Thu, 18 Jun 2009 18:42:32 GMT]]></title><description><![CDATA[<p>Sebastian Pizer schrieb:</p>
<blockquote>
<pre><code class="language-cpp">Matrix operator+(Matrix const&amp; lhs, Matrix const&amp; rhs)
{
  Matrix result = lhs;
  lhs += rhs;
  return result;
}
</code></pre>
</blockquote>
<p>Upps... die mittlere Zeile sollte natürlich &quot;result += rhs;&quot; heissen.</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1729029</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1729029</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Thu, 18 Jun 2009 18:42:32 GMT</pubDate></item><item><title><![CDATA[Reply to Copy-Konstruktor und Operatoren&#x2F;Methoden on Thu, 18 Jun 2009 18:55:03 GMT]]></title><description><![CDATA[<p>Man kann auch</p>
<pre><code class="language-cpp">Matrix operator+(Matrix const&amp; lhs, Matrix const&amp; rhs)
{
    return Matrix(lhs) += rhs;
}
</code></pre>
<p>schreiben. <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>
<p>(Zumindest wenn <code>operator+=</code> eine Referenz auf <code>*this</code> zurückgibt)...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1729035</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1729035</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 18 Jun 2009 18:55:03 GMT</pubDate></item><item><title><![CDATA[Reply to Copy-Konstruktor und Operatoren&#x2F;Methoden on Thu, 18 Jun 2009 20:41:09 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Man kann auch</p>
<pre><code class="language-cpp">Matrix operator+(Matrix const&amp; lhs, Matrix const&amp; rhs)
{
    return Matrix(lhs) += rhs;
}
</code></pre>
<p>schreiben. <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>
<p>(Zumindest wenn <code>operator+=</code> eine Referenz auf <code>*this</code> zurückgibt)...</p>
</blockquote>
<p>Klar kann man das. Aber es macht einen Unterschied. Bei Dir steht in der Return-Anweisung ein Funktionsaufruf der &quot;irgendeine&quot; Referenz zurückgiebt. Das erschwert die Return-Value-Optimierung unnötig. Schreibst Du dagegen</p>
<pre><code class="language-cpp">Matrix operator+(Matrix const&amp; lhs, Matrix const&amp; rhs)
{
    Matrix ret (lhs);
    ret += rhs;
    return ret;
}
</code></pre>
<p>ist dem Compiler klar, welches Objekt da zurückgegeben werden soll.</p>
<p>Ich habe es gerade eben nochmal ausprobiert: g++ kann bei Deiner Kurzversion keine RVO durchführen. Mit der längeren Version sparst Du Dir eine Kopie des Matrix-Objektes.</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1729108</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1729108</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Thu, 18 Jun 2009 20:41:09 GMT</pubDate></item><item><title><![CDATA[Reply to Copy-Konstruktor und Operatoren&#x2F;Methoden on Thu, 18 Jun 2009 20:45:18 GMT]]></title><description><![CDATA[<p>Sebastian Pizer schrieb:</p>
<blockquote>
<p>Klar kann man das. Aber es macht einen Unterschied. Bei Dir steht in der Return-Anweisung ein Funktionsaufruf der &quot;irgendeine&quot; Referenz zurückgiebt. Das erschwert die Return-Value-Optimierung unnötig.</p>
</blockquote>
<p>Wirklich? Ich hätte jetzt eher auf das Umgekehrte getippt, also dass ein kurzer temporärer Ausdruck viel eher wegoptimiert werden kann.</p>
<p>Wie meinst du das mit irgendeiner Referenz? Es sollte dem Compiler doch klar sein, welcher RValue nicht kopiert werden muss. Oder etwa nicht?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1729114</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1729114</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 18 Jun 2009 20:45:18 GMT</pubDate></item><item><title><![CDATA[Reply to Copy-Konstruktor und Operatoren&#x2F;Methoden on Thu, 18 Jun 2009 21:03:44 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Wie meinst du das mit irgendeiner Referenz? Es sollte dem Compiler doch klar sein, welcher RValue nicht kopiert werden muss. Oder etwa nicht?</p>
</blockquote>
<p>Mit &quot;irgendeiner&quot; Referenz meinte ich die Tatsache, dass man der Signatur der operator+= Funktion</p>
<pre><code class="language-cpp">class Matrix {
   ...
   Matrix&amp; operator+=(Matrix const&amp;);
   ...
};
</code></pre>
<p>nicht ansieht, was für eine Referenz diese Funktion zurückgegen wird. Es muss ja nicht eine Referenz auf *this sein. RVO kann nur dann funktionieren, wenn sich der Compiler sicher sein kann, dass der Ausdruck in der Return-Anweisung ein bestimmtes lokales Objekt referenziert. Das ist bei einem Funktionsaufruf, der eine Referenz zurückgiebt nicht gegeben -- es sei denn es handelt sich um eine Inline-Funktion und der Compiler ist übermäßig schlau (trifft auf g++ aber nicht zu).</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1729128</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1729128</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Thu, 18 Jun 2009 21:03:44 GMT</pubDate></item><item><title><![CDATA[Reply to Copy-Konstruktor und Operatoren&#x2F;Methoden on Thu, 18 Jun 2009 21:34:16 GMT]]></title><description><![CDATA[<p>Ah, das macht natürlich Sinn. Ich habe bisher in C++ nicht wahnsinnig auf RVO Rücksicht genommen, in Zukunft werde ich wohl vermehrt darauf achten. Zumindest versuche ich, diesbezüglich etwas transparenter zu programmieren. <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>Vielen Dank für die Erklärung!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1729139</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1729139</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 18 Jun 2009 21:34:16 GMT</pubDate></item></channel></rss>