<?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[Konzept Multiplikationsoperator einer Matrix]]></title><description><![CDATA[<p>Hallo Leute,</p>
<p>ich stecke in einem Kreis aus Problemen. Ich habe eine Matrizenmultiplikation. Und komme nicht raus auf bereits gelöschte Daten zuzugreifen.</p>
<p>Hier der Multiplikationsoperator. Er soll mir ein Objekt der Klasse lapack_matrix zurückgeben. Diese Klasse beherbergt einen double Zeiger mit Daten die dynamisch angelegt werden.</p>
<pre><code class="language-cpp">lapack_matrix lapack_matrix::operator*(lapack_matrix &amp;rhs) const
{
	if( (GetCols() == rhs.GetRows()) &amp;&amp; (GetRows() == rhs.GetCols()) )
	{
 		double *tmp = new double[GetRows()*rhs.GetCols()];

		if(tmp != NULL)
		{
			memset(tmp,0x00,std::size_t(GetRows()*rhs.GetCols()*sizeof(double)));
			const int m = GetRows();
			const int n = rhs.GetCols();
			const int k = GetCols();

			const double alpha = 1.0;
			const double beta = 1.0;
			const int ldb = rhs.GetRows();

			dgemm_(	GetTransposed() ? &quot;T&quot; : &quot;N&quot;, // OPERATOR A
					rhs.GetTransposed() ? &quot;T&quot; : &quot;N&quot;, // OPERATOR B
					&amp;m, // NUMBER OF ROWS IN OPERATOR(A)
					&amp;n, // NUMBER OF COLS IN OPERATOR (B)
					&amp;k, // NUMBER OF COLS IN OPERATOR (A)
					&amp;alpha, // ALPHA
					data, // A
					&amp;rows, // LDA
					rhs.GetRawData(), // B
					&amp;ldb, // LDB
					&amp;beta, // FACTOR B
					tmp, // C
					&amp;m // LDC
				);

			 lapack_matrix tmpm(rhs.GetCols(),GetRows(),tmp);

			 delete tmp;

			 return tmpm;
		}

		assert(false);
	}

	assert(false);

	return lapack_matrix();
}
</code></pre>
<p>Hier der Destruktor zur Klasse</p>
<pre><code class="language-cpp">lapack_matrix::~lapack_matrix()
{
	if(data != NULL)
	{
		delete data;
		data = NULL;
	}
}
</code></pre>
<p>Hier der in Zeile 33 beteiligte Konstruktor</p>
<pre><code class="language-cpp">lapack_matrix::lapack_matrix(int newCols, int newRows,double *newData) : 
cols(newCols),
rows(newRows)
{
	if(init())
	{
		if(newData != NULL)
		{
			data = new double[newCols*newRows];

			if(data != NULL)
			{
				memcpy(data,newData,std::size_t(newCols*newRows*sizeof(double)));
				return;
			}

			assert(false);
		}

		assert(false);
	}

	assert(false);
}
</code></pre>
<p>und der Kopierkonstruktor</p>
<pre><code class="language-cpp">lapack_matrix::lapack_matrix(const lapack_matrix &amp;rhs) : 
rows(rhs.GetRealRows()),
cols(rhs.GetRealCols()),
transposed(GetTransposed()),
symmetric(GetSymmetric())
{
	if(init())
	{
		double *data = new double[rhs.GetRows()*rhs.GetCols()];

		if( data != NULL )
		{
			memcpy(data,rhs.GetData(),std::size_t(rhs.GetRows()*rhs.GetCols()*sizeof(double)));
			return;
		}
	}

	rows = 0;
	cols = 0;
	transposed = false;
	symmetric = false;
}
</code></pre>
<p>Dieser Code verursacht einen Fehler:</p>
<pre><code class="language-cpp">lapack_matrix C = matrix1*matrix2;
</code></pre>
<p>Beim Verlassen der Zeile 37 ist C.data = NULL<br />
Warum ist es so? Ich lege doch eine Kopie an?<br />
Gibt es ein Standardverhalten bezüglich 45? Was sollte man zurückgeben wenn keine gültige Matrix erstellt werden kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/287960/konzept-multiplikationsoperator-einer-matrix</link><generator>RSS for Node</generator><lastBuildDate>Thu, 20 Aug 2026 05:04:22 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/287960.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 07 Jun 2011 19:21:03 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 19:21:03 GMT]]></title><description><![CDATA[<p>Hallo Leute,</p>
<p>ich stecke in einem Kreis aus Problemen. Ich habe eine Matrizenmultiplikation. Und komme nicht raus auf bereits gelöschte Daten zuzugreifen.</p>
<p>Hier der Multiplikationsoperator. Er soll mir ein Objekt der Klasse lapack_matrix zurückgeben. Diese Klasse beherbergt einen double Zeiger mit Daten die dynamisch angelegt werden.</p>
<pre><code class="language-cpp">lapack_matrix lapack_matrix::operator*(lapack_matrix &amp;rhs) const
{
	if( (GetCols() == rhs.GetRows()) &amp;&amp; (GetRows() == rhs.GetCols()) )
	{
 		double *tmp = new double[GetRows()*rhs.GetCols()];

		if(tmp != NULL)
		{
			memset(tmp,0x00,std::size_t(GetRows()*rhs.GetCols()*sizeof(double)));
			const int m = GetRows();
			const int n = rhs.GetCols();
			const int k = GetCols();

			const double alpha = 1.0;
			const double beta = 1.0;
			const int ldb = rhs.GetRows();

			dgemm_(	GetTransposed() ? &quot;T&quot; : &quot;N&quot;, // OPERATOR A
					rhs.GetTransposed() ? &quot;T&quot; : &quot;N&quot;, // OPERATOR B
					&amp;m, // NUMBER OF ROWS IN OPERATOR(A)
					&amp;n, // NUMBER OF COLS IN OPERATOR (B)
					&amp;k, // NUMBER OF COLS IN OPERATOR (A)
					&amp;alpha, // ALPHA
					data, // A
					&amp;rows, // LDA
					rhs.GetRawData(), // B
					&amp;ldb, // LDB
					&amp;beta, // FACTOR B
					tmp, // C
					&amp;m // LDC
				);

			 lapack_matrix tmpm(rhs.GetCols(),GetRows(),tmp);

			 delete tmp;

			 return tmpm;
		}

		assert(false);
	}

	assert(false);

	return lapack_matrix();
}
</code></pre>
<p>Hier der Destruktor zur Klasse</p>
<pre><code class="language-cpp">lapack_matrix::~lapack_matrix()
{
	if(data != NULL)
	{
		delete data;
		data = NULL;
	}
}
</code></pre>
<p>Hier der in Zeile 33 beteiligte Konstruktor</p>
<pre><code class="language-cpp">lapack_matrix::lapack_matrix(int newCols, int newRows,double *newData) : 
cols(newCols),
rows(newRows)
{
	if(init())
	{
		if(newData != NULL)
		{
			data = new double[newCols*newRows];

			if(data != NULL)
			{
				memcpy(data,newData,std::size_t(newCols*newRows*sizeof(double)));
				return;
			}

			assert(false);
		}

		assert(false);
	}

	assert(false);
}
</code></pre>
<p>und der Kopierkonstruktor</p>
<pre><code class="language-cpp">lapack_matrix::lapack_matrix(const lapack_matrix &amp;rhs) : 
rows(rhs.GetRealRows()),
cols(rhs.GetRealCols()),
transposed(GetTransposed()),
symmetric(GetSymmetric())
{
	if(init())
	{
		double *data = new double[rhs.GetRows()*rhs.GetCols()];

		if( data != NULL )
		{
			memcpy(data,rhs.GetData(),std::size_t(rhs.GetRows()*rhs.GetCols()*sizeof(double)));
			return;
		}
	}

	rows = 0;
	cols = 0;
	transposed = false;
	symmetric = false;
}
</code></pre>
<p>Dieser Code verursacht einen Fehler:</p>
<pre><code class="language-cpp">lapack_matrix C = matrix1*matrix2;
</code></pre>
<p>Beim Verlassen der Zeile 37 ist C.data = NULL<br />
Warum ist es so? Ich lege doch eine Kopie an?<br />
Gibt es ein Standardverhalten bezüglich 45? Was sollte man zurückgeben wenn keine gültige Matrix erstellt werden kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074893</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074893</guid><dc:creator><![CDATA[neuling21]]></dc:creator><pubDate>Tue, 07 Jun 2011 19:21:03 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 19:27:21 GMT]]></title><description><![CDATA[<blockquote>
<p>Was sollte man zurückgeben wenn keine gültige Matrix erstellt werden kann?</p>
</blockquote>
<p>Nicht, man wirft eine Exception.</p>
<p>Und mach mal den Rückgabewert und den Parameter vom Operator <code>const</code> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074895</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074895</guid><dc:creator><![CDATA[EOutOfResources]]></dc:creator><pubDate>Tue, 07 Jun 2011 19:27:21 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 19:28:21 GMT]]></title><description><![CDATA[<p>Du hast im Kopier-Konstruktor eine lokale Variable &quot;double* data&quot; angelegt, die die Klassen-Variable überdeckt.</p>
<p>PS: Ist es nicht ein wenig sinnlos, die Member transposed und symmetric mit sich selbst du initialisieren?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074896</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074896</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 07 Jun 2011 19:28:21 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 19:29:04 GMT]]></title><description><![CDATA[<p>hab den fehler in zeile 9 des dritten quelltextes gefunden. das &quot;double *&quot; muss dort weg.. blöder fehler.</p>
<p>Bin für weitere Anregungen dennoch dankbar.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074897</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074897</guid><dc:creator><![CDATA[neuling21]]></dc:creator><pubDate>Tue, 07 Jun 2011 19:29:04 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 19:29:58 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>Du hast im Kopier-Konstruktor eine lokale Variable &quot;double* data&quot; angelegt, die die Klassen-Variable überdeckt.</p>
<p>PS: Ist es nicht ein wenig sinnlos, die Member transposed und symmetric mit sich selbst du initialisieren?</p>
</blockquote>
<p>Super du hast den Fehler gleich gefunden.. und einen weiteren Bug. Danke dir!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074898</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074898</guid><dc:creator><![CDATA[neuling21]]></dc:creator><pubDate>Tue, 07 Jun 2011 19:29:58 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 19:35:59 GMT]]></title><description><![CDATA[<p>Ich würde den Destruktor noch auf eine einzige Zeile reduzieren. Denn es ist sehr unwahrscheinlich, dass jemand ihn mehrfach aufruft.</p>
<p>Und der Gleichheitsvergleich mit 0 und der Rückgabe von <code>new</code> ist sinnlos. Denn mit dem letzten Standard sollte ein gescheitertes <code>new</code> ein <code>std::bad_alloc</code> werfen statt 0 zu sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074899</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074899</guid><dc:creator><![CDATA[EOutOfResources]]></dc:creator><pubDate>Tue, 07 Jun 2011 19:35:59 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 19:46:13 GMT]]></title><description><![CDATA[<p>EOutOfResources schrieb:</p>
<blockquote>
<p>Ich würde den Destruktor noch auf eine einzige Zeile reduzieren. Denn es ist sehr unwahrscheinlich, dass jemand ihn mehrfach aufruft.</p>
<p>Und der Gleichheitsvergleich mit 0 und der Rückgabe von <code>new</code> ist sinnlos. Denn mit dem letzten Standard sollte ein gescheitertes <code>new</code> ein <code>std::bad_alloc</code> werfen statt 0 zu sein.</p>
</blockquote>
<p>Sehe ich das richtig dass eine Abfrage auf 0 dann sogar zum falschen Verhalten führen kann?</p>
<p>Also soll ich:</p>
<pre><code class="language-cpp">try
{
new ...
}
catch(std::bad_alloc &amp;e)
{
 exit(-1);
}
</code></pre>
<p>Könnte man irgendwie diese Matrix Kopiererei (1 Code Zeile 1 bezüglich Zeile 37) irgendwie durch Referenzen unterbinden?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074906</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074906</guid><dc:creator><![CDATA[neuling21]]></dc:creator><pubDate>Tue, 07 Jun 2011 19:46:13 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 19:49:30 GMT]]></title><description><![CDATA[<p>neuling21 schrieb:</p>
<blockquote>
<pre><code class="language-cpp">try
{
new ...
}
catch(std::bad_alloc &amp;e)
{
 exit(-1);
}
</code></pre>
</blockquote>
<p>Schon besser. Ich würde es in ein Log schreiben oder eine Meldung bringen. Und die abzufangende Exception muss keinen Namen haben.</p>
<p>neuling21 schrieb:</p>
<blockquote>
<p>Könnte man irgendwie diese Matrix Kopiererei (1 Code Zeile 1 bezüglich Zeile 37) irgendwie durch Referenzen unterbinden?</p>
</blockquote>
<p>Nein, denn es sind lokale Instanzen. In C++0x gibt es Move-Semantics für exakt diesen Fall.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074909</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074909</guid><dc:creator><![CDATA[EOutOfResources]]></dc:creator><pubDate>Tue, 07 Jun 2011 19:49:30 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 19:52:37 GMT]]></title><description><![CDATA[<p>Ich glaube ein std::valarray führt bereits genau das aus, was du hier vor hast. (Ich hab mich schon länger nicht mehr mit der Matrizenrechnung befasst, kann sein, dass das völliger Blödsinn ist -&gt; Doku)<br />
Ich glaube ausserdem, dass boost bereits eine fertige Matrizen-Klasse enthält.</p>
<p>Ich würde jedenfalls die Größe der Matrix als template-Parameter verwenden, dadurch löst sich das Problem von selbst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074911</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074911</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Tue, 07 Jun 2011 19:52:37 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 19:57:26 GMT]]></title><description><![CDATA[<p>EOutOfResources schrieb:</p>
<blockquote>
<p>neuling21 schrieb:</p>
<blockquote>
<pre><code class="language-cpp">try
{
new ...
}
catch(std::bad_alloc &amp;e)
{
 exit(-1);
}
</code></pre>
</blockquote>
<p>Schon besser. Ich würde es in ein Log schreiben oder eine Meldung bringen. Und die abzufangende Exception muss keinen Namen haben.</p>
<p>neuling21 schrieb:</p>
<blockquote>
<p>Könnte man irgendwie diese Matrix Kopiererei (1 Code Zeile 1 bezüglich Zeile 37) irgendwie durch Referenzen unterbinden?</p>
</blockquote>
<p>Nein, denn es sind lokale Instanzen. In C++0x gibt es Move-Semantics für exakt diesen Fall.</p>
</blockquote>
<p>Danke dir schonmal für deine Hilfe.</p>
<p>Meinst du mit Move Sematics so etwas?</p>
<pre><code class="language-cpp">constexpr lapack_matrix lapack_matrix::operator*(lapack_matrix &amp;rhs) const
</code></pre>
<p>Dieses Rumkopieren ist bisher der einzige Wehmutstropfen. Man spürt eine deutliche Verzögerung bei größeren Matrizen gegenüber nativem LAPACK</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074914</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074914</guid><dc:creator><![CDATA[neuling21]]></dc:creator><pubDate>Tue, 07 Jun 2011 19:57:26 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 19:59:59 GMT]]></title><description><![CDATA[<p>Da wäre es eventuell eine Idee, deine Matrix-Klasse mit Referenzzhälung und copy-on-write Funktionalität auszustatten. (d.h. der Speicher wird erst wirklich kopiert, wenn einer der Verwender etwas daran ändern will)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074915</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074915</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 07 Jun 2011 19:59:59 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 20:03:11 GMT]]></title><description><![CDATA[<p>neuling21 schrieb:</p>
<blockquote>
<pre><code class="language-cpp">constexpr lapack_matrix lapack_matrix::operator*(lapack_matrix &amp;rhs) const
</code></pre>
</blockquote>
<p>Nein:</p>
<pre><code class="language-cpp">lapack_matrix&amp;&amp; lapack_matrix::operator*(lapack_matrix &amp;rhs) const
</code></pre>
<p>Und wie ich bereits gesagt habe (lesen?) sollst du den Parameter und den Rückgabewert <code>const</code> machen!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074918</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074918</guid><dc:creator><![CDATA[EOutOfResources]]></dc:creator><pubDate>Tue, 07 Jun 2011 20:03:11 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 20:07:56 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>Da wäre es eventuell eine Idee, deine Matrix-Klasse mit Referenzzhälung und copy-on-write Funktionalität auszustatten. (d.h. der Speicher wird erst wirklich kopiert, wenn einer der Verwender etwas daran ändern will)</p>
</blockquote>
<p>Ist es so etwas wie ein proxy pattern? Im worst case hätte ich aber immer noch dieses herumkopiere..</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074923</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074923</guid><dc:creator><![CDATA[neuling21]]></dc:creator><pubDate>Tue, 07 Jun 2011 20:07:56 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 20:09:48 GMT]]></title><description><![CDATA[<p>EOutOfResources schrieb:</p>
<blockquote>
<p>neuling21 schrieb:</p>
<blockquote>
<pre><code class="language-cpp">constexpr lapack_matrix lapack_matrix::operator*(lapack_matrix &amp;rhs) const
</code></pre>
</blockquote>
<p>Nein:</p>
<pre><code class="language-cpp">lapack_matrix&amp;&amp; lapack_matrix::operator*(lapack_matrix &amp;rhs) const
</code></pre>
<p>Und wie ich bereits gesagt habe (lesen?) sollst du den Parameter und den Rückgabewert <code>const</code> machen!</p>
</blockquote>
<p>Wurde sofort gemacht <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="🙂"
    /> Nur habe ich es hier im Forum aus dem oberen Beitrag kopiert. Danke</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074926</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074926</guid><dc:creator><![CDATA[neuling21]]></dc:creator><pubDate>Tue, 07 Jun 2011 20:09:48 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 20:17:01 GMT]]></title><description><![CDATA[<p>neuling21 schrieb:</p>
<blockquote>
<p>Ist es so etwas wie ein proxy pattern? Im worst case hätte ich aber immer noch dieses herumkopiere..</p>
</blockquote>
<p>Bei den Pattern bin ich nicht 100% sattelfest, aber in dieser Anwendung ersparst du dir das Kopieren auf jeden Fall (das Original, von dem kopiert wird, verschwindet sofort im Nirvana - und am Ende ist C der einzige, der die Daten verwendet).</p>
<p>In den Worst-Case-Fällen, wo du um die tatsächliche Kopie nicht herumkommst, hättest du vermutlich auch mit dem C-Code, den du hier versteckst, deinen Spiecherbereich kopieren müssen, also dürfte das kein so großes Proble sein:</p>
<pre><code class="language-cpp">lapack_matrix M1 = ...;
lapack_matrix M2 = M1;
M2(0,0) = -1;//hier wird tatsächlich eine Kopie notwendig
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2074933</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074933</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 07 Jun 2011 20:17:01 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 20:20:54 GMT]]></title><description><![CDATA[<p>EOutOfResources schrieb:</p>
<blockquote>
<pre><code class="language-cpp">lapack_matrix&amp;&amp; lapack_matrix::operator*(lapack_matrix &amp;rhs) const
</code></pre>
<p>Und wie ich bereits gesagt habe (lesen?) sollst du den Parameter und den Rückgabewert <code>const</code> machen!</p>
</blockquote>
<p>Wurde sofort gemacht <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="🙂"
    /> Nur habe ich es hier im Forum aus dem oberen Beitrag kopiert. Danke[/quote]</p>
<p>Entschuldige dass ich nochmal hinterfragen muss aber ich bekomme im oberen Code diesen fehler. Selbst wenn ich const lapack_matrix tmp(...) mache.</p>
<pre><code>error C2440: 'return' : cannot convert from 'lapack_matrix' to 'const lapack_matrix &amp;&amp;'
You cannot bind an lvalue to an rvalue reference
</code></pre>
<p>Gibt es schon ein Buch dass in den neuen Standard reinschnüffelt solche tips gut beschreibt und zudem möglichst deutsch (einfaches englisch) ist?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074937</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074937</guid><dc:creator><![CDATA[neuling21]]></dc:creator><pubDate>Tue, 07 Jun 2011 20:20:54 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 20:22:59 GMT]]></title><description><![CDATA[<p>Der Standard ist noch nicht verabschiedet. Welchen Compiler hast du?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074938</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074938</guid><dc:creator><![CDATA[EOutOfResources]]></dc:creator><pubDate>Tue, 07 Jun 2011 20:22:59 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 20:34:13 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>Bei den Pattern bin ich nicht 100% sattelfest, aber in dieser Anwendung ersparst du dir das Kopieren auf jeden Fall (das Original, von dem kopiert wird, verschwindet sofort im Nirvana - und am Ende ist C der einzige, der die Daten verwendet).</p>
<p>In den Worst-Case-Fällen, wo du um die tatsächliche Kopie nicht herumkommst, hättest du vermutlich auch mit dem C-Code, den du hier versteckst, deinen Spiecherbereich kopieren müssen, also dürfte das kein so großes Proble sein:</p>
<pre><code class="language-cpp">lapack_matrix M1 = ...;
lapack_matrix M2 = M1;
M2(0,0) = -1;//hier wird tatsächlich eine Kopie notwendig
</code></pre>
</blockquote>
<p>Das hört sich gut an. Auch die Klammer als Elementzugriffsoperator zu gebrauchen... hab gar nicht daran gedacht.</p>
<p>Ich führe also in jeder Klasse einen Zeiger auf lapack_data der ersten Matrix:</p>
<pre><code class="language-cpp">class lapack_data
{
  public:
   double *data;
   unsigned int ref;
}
</code></pre>
<p>und im Destruktor</p>
<pre><code class="language-cpp">lapack_matrix::~lapack_matrix
{
  if( ((*lapack_data)--) == 0 )
  {
    delete lapack_data;
  }
}
</code></pre>
<p>Bei lesenden Funktionen greife ich ganz normal auf double * zu. Sobald ich einmal etwas ändere Rufe ich eine Funktion auf die:<br />
-mir den double Zeiger kopiert.<br />
-Referenz herunterzählt.<br />
-Wenn Referenz == 0 dann lapack_data löscht<br />
Habe ich dich richtig verstanden?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074940</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074940</guid><dc:creator><![CDATA[neuling21]]></dc:creator><pubDate>Tue, 07 Jun 2011 20:34:13 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 20:35:03 GMT]]></title><description><![CDATA[<p>EOutOfResources schrieb:</p>
<blockquote>
<p>Der Standard ist noch nicht verabschiedet. Welchen Compiler hast du?</p>
</blockquote>
<p>MS Visual Studio 2010 SP1</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074941</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074941</guid><dc:creator><![CDATA[neuling21]]></dc:creator><pubDate>Tue, 07 Jun 2011 20:35:03 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 20:45:39 GMT]]></title><description><![CDATA[<p>neuling21 schrieb:</p>
<blockquote>
<p>und im Destruktor</p>
<pre><code class="language-cpp">lapack_matrix::~lapack_matrix
{
  if( ((*lapack_data)--) == 0 )
  {
    delete lapack_data;
  }
}
</code></pre>
</blockquote>
<p>eher <code>(--lapack_data-&gt;ref)==0</code> , aber ansonsten sieht es so richtig aus.<br />
Du solltest nur daran denken, daß Kopier-Konstruktor und operator= das Spiel auch mitmachen.</p>
<blockquote>
<p>Bei lesenden Funktionen greife ich ganz normal auf double * zu. Sobald ich einmal etwas ändere Rufe ich eine Funktion auf die:<br />
-mir den double Zeiger kopiert.<br />
-Referenz herunterzählt.<br />
-Wenn Referenz == 0 dann lapack_data löscht<br />
Habe ich dich richtig verstanden?</p>
</blockquote>
<p>Fast - wenn ref==1 ist, brauchst du nicht zu kopieren, sondern kannst normal mit den vorhandenen Daten arbeiten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074946</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074946</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 07 Jun 2011 20:45:39 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 20:48:11 GMT]]></title><description><![CDATA[<p>EOutOfResources schrieb:</p>
<blockquote>
<p>Nein:</p>
<pre><code class="language-cpp">lapack_matrix&amp;&amp; lapack_matrix::operator*(lapack_matrix &amp;rhs) const
</code></pre>
</blockquote>
<p>Wie kommst du nur auf die Idee, eine RValue Referenz auf eine lokale Variable zurückzugeben. RValue Referenzen _sind_ auch nur Referenzen! Eine ganz normale Wert-rückgabe, allerdings mit move, gehört hier her.</p>
<p>Move-Semantiks bedeutet, dass es einen Move Ctor gibt, der Move op = kann über den Move Ctor sehr einfach implementiert werden, indem man das Objekt per Value nimmt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074947</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074947</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Tue, 07 Jun 2011 20:48:11 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 21:06:16 GMT]]></title><description><![CDATA[<p>314159265358979 schrieb:</p>
<blockquote>
<p>EOutOfResources schrieb:</p>
<blockquote>
<p>Nein:</p>
<pre><code class="language-cpp">lapack_matrix&amp;&amp; lapack_matrix::operator*(lapack_matrix &amp;rhs) const
</code></pre>
</blockquote>
<p>Wie kommst du nur auf die Idee, eine RValue Referenz auf eine lokale Variable zurückzugeben. RValue Referenzen _sind_ auch nur Referenzen! Eine ganz normale Wert-rückgabe, allerdings mit move, gehört hier her.</p>
<p>Move-Semantiks bedeutet, dass es einen Move Ctor gibt, der Move op = kann über den Move Ctor sehr einfach implementiert werden, indem man das Objekt per Value nimmt.</p>
</blockquote>
<p>Wäre dir für ein Beispiel sehr dankbar.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074955</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074955</guid><dc:creator><![CDATA[neuling21]]></dc:creator><pubDate>Tue, 07 Jun 2011 21:06:16 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 21:18:09 GMT]]></title><description><![CDATA[<p>Move-Konstruktor:</p>
<pre><code class="language-cpp">Object(Object&amp;&amp; other)
    : some_variables(other.some_variables)
{
    other.some_variables = some_default_value;
}
</code></pre>
<p>Hier werden die Ressourcen von other &quot;geklaut&quot;. Wichtig ist dabei, dass other weiterhin ein gültiges Objekt ist, mit dem gearbeitet werden kann.</p>
<p>op =:</p>
<pre><code class="language-cpp">Object&amp; operator = (Object rhs) // ganz normale Werte-übergabe
{
    rhs.swap(*this);
    return *this;
}
</code></pre>
<p>Diese operator = kann sowohl kopieren, als auch moven. Er wird deswegen auch gerne als &quot;unified assignment-operator&quot; bezeichnet. Wenn ein R-Value übergeben wird, wird das rhs-Objekt move-constructed, sprich, der Move-Konstruktor wird für rhs aufgerufen. Wird ein L-Value übergeben, dann wird der normale Copy-Ctor aufgerufen.</p>
<p>Mit diesem assignment operator entfällt auch der nervige Check, ob other == *this, außerdem ist er Excepion-Save, ein swap() sollte niemals etwas werfen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074959</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074959</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Tue, 07 Jun 2011 21:18:09 GMT</pubDate></item><item><title><![CDATA[Reply to Konzept Multiplikationsoperator einer Matrix on Tue, 07 Jun 2011 22:05:21 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>Da wäre es eventuell eine Idee, deine Matrix-Klasse mit Referenzzhälung und copy-on-write Funktionalität auszustatten. (d.h. der Speicher wird erst wirklich kopiert, wenn einer der Verwender etwas daran ändern will)</p>
</blockquote>
<p>Oder nur C++98-Move-Semantik à la <code>auto_ptr</code> , sofern man keine Wertsemantik benötigt. Ist noch etwas günstiger als <code>intrusive_ptr</code> , was hier ja im Prinzip nachgebaut wird.</p>
<p>314159265358979 schrieb:</p>
<blockquote>
<p>Eine ganz normale Wert-rückgabe, allerdings mit move, gehört hier her.</p>
</blockquote>
<p>Ohne <code>std::move()</code> , eine funktionslokale Variable existiert nicht länger. Move-Konstruktoren können implizit generiert und aufgerufen werden.</p>
<p>Aber heutige Compiler können schon recht gut RVO. Allerdings muss man ein paar Dinge beachten, um die Optimierung nicht zu verhindern.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074984</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074984</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 07 Jun 2011 22:05:21 GMT</pubDate></item></channel></rss>