<?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[[gelöst]Unterschied Typumwandlungskonstrutor zu Allgemeinen Konstruktor]]></title><description><![CDATA[<p>Guten Abend,</p>
<p>ich lese mich gerade in den Typumwandlungskontruktor ein und verstehe nicht ganz wie man diesen von einem Allgemeinen Konstruktor unterscheiden kann. Bei einem Kopierkonstruktor z.B. wird ja eine Referenz auf dieselbe Klasse als Argument mit übergeben und daran erkennt man ihn dann, aber wie erkennt der Compiler einen Typumwandlungskonstruktor? Wenn es wirklich zwei unterschiedliche Dinge sind dann müssten ja auch die Signaturen unterschiedlich sein oder?</p>
<p>G hibbes</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/267495/gelöst-unterschied-typumwandlungskonstrutor-zu-allgemeinen-konstruktor</link><generator>RSS for Node</generator><lastBuildDate>Wed, 02 Sep 2026 12:01:08 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/267495.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 25 May 2010 17:59:05 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [gelöst]Unterschied Typumwandlungskonstrutor zu Allgemeinen Konstruktor on Wed, 26 May 2010 06:28:03 GMT]]></title><description><![CDATA[<p>Guten Abend,</p>
<p>ich lese mich gerade in den Typumwandlungskontruktor ein und verstehe nicht ganz wie man diesen von einem Allgemeinen Konstruktor unterscheiden kann. Bei einem Kopierkonstruktor z.B. wird ja eine Referenz auf dieselbe Klasse als Argument mit übergeben und daran erkennt man ihn dann, aber wie erkennt der Compiler einen Typumwandlungskonstruktor? Wenn es wirklich zwei unterschiedliche Dinge sind dann müssten ja auch die Signaturen unterschiedlich sein oder?</p>
<p>G hibbes</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1902416</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1902416</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Wed, 26 May 2010 06:28:03 GMT</pubDate></item><item><title><![CDATA[Reply to [gelöst]Unterschied Typumwandlungskonstrutor zu Allgemeinen Konstruktor on Tue, 25 May 2010 18:16:20 GMT]]></title><description><![CDATA[<p>Das ist an sich nichts besonderes: Bei Zuweisungen wird automatisch geguckt, ob ein passender Konstruktor mit <strong>genau einem</strong> Argument vorhanden ist. Eigentlich genau wie beim Kopierkonstruktor, nur mit einem anderen Argumententyp.</p>
<p>Falls du die automatische Umwandlung nicht wünscht, musst du den entsprechenden Konstruktor <code>explicit</code> machen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1902434</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1902434</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 25 May 2010 18:16:20 GMT</pubDate></item><item><title><![CDATA[Reply to [gelöst]Unterschied Typumwandlungskonstrutor zu Allgemeinen Konstruktor on Tue, 25 May 2010 23:18:33 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>Das ist an sich nichts besonderes: Bei Zuweisungen wird automatisch geguckt, ob ein passender Konstruktor mit <strong>genau einem</strong> Argument vorhanden ist. Eigentlich genau wie beim Kopierkonstruktor, nur mit einem anderen Argumententyp.</p>
</blockquote>
<p>Genauer: mit min. einem Argument und max. einem Argument welches keinen Default-Wert hat (wobei auch alle Argumente einen Default-Wert haben dürfen).<br />
Dasselbe gilt im Übrigen auch für den Copy-Ctor.<br />
Und der Default-Ctor darf auch ruhig Argumente haben, so lange alle einen Default-Wert haben.</p>
<p>Beispiel:</p>
<pre><code class="language-cpp">class foo
{
public:
	static foo f;
	foo(int a, int b = 123) {} // A
	foo(void* p, void* p2 = 0) {} // B (auch &quot;p&quot; dürfte einen default-wert haben, nur dann hätten wir mit C zwei default-konstruktoren, was nicht OK ist)
	foo(foo const&amp; foo = f, int* p = 0) {} // C - copy ctor + default ctor
};

foo foo::f; // calls C   EDIT: das ist natürlich unfug, da hier C mit dem default-wert aufgerufen würde,
            //           und der default-wert ist f. also genau das objekt welches initialisiert werden soll. henne/ei und so.
            //           syntaktisch OK, aber totaler unfug und zur laufzeit undefiniertes verhalten.
            //           man müsste f also mit einem anderen konstruktor initialisieren, dann wäre es OK

void bar(foo f)
{
}

foo bar()
{
	foo f; // calls C as default-ctor
	bar(&quot;seppdepp&quot;); // calls B
	return 1; // calls A
}

int main()
{
	foo f(bar()); // may call C as copy-ctor (may be elided via RVO)
	foo f2 = f; // calls C as copy-ctor
}
</code></pre>
<p>EDIT: siehe code</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1902502</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1902502</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 25 May 2010 23:18:33 GMT</pubDate></item><item><title><![CDATA[Reply to [gelöst]Unterschied Typumwandlungskonstrutor zu Allgemeinen Konstruktor on Tue, 25 May 2010 21:42:02 GMT]]></title><description><![CDATA[<p>Danke für die wirklich ausführlichen Erklärungen. Ein Konstruktoraufruf macht mich erstmal stutzig, aber is ja auch schon spät <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>
<pre><code class="language-cpp">foo bar()
{
    foo f; // calls C as default-ctor
    bar(&quot;seppdepp&quot;); // calls B
    return 1; // calls A: nicht doch C weil copy und default hier eins sind?
}
</code></pre>
<p>Wird hier nicht bei dem Return der Copy-Ctor aufgerufen, bei meinen Tests wird der aufgerufen wenn das Objekt der Klasse per Kopie übergeben wird und wenn es eine Rückgabe vom Typ der Klasse gibt?</p>
<p>G hibbes</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1902528</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1902528</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Tue, 25 May 2010 21:42:02 GMT</pubDate></item><item><title><![CDATA[Reply to [gelöst]Unterschied Typumwandlungskonstrutor zu Allgemeinen Konstruktor on Tue, 25 May 2010 22:55:39 GMT]]></title><description><![CDATA[<p>Naja, ist ja nicht schwer auszuprobieren:</p>
<pre><code class="language-cpp">#include &quot;stdafx.h&quot;
#include &lt;iostream&gt;

class foo
{
public:
	char const* m_a;

	foo(char const* a)
	{
		m_a = a;
		std::cout &lt;&lt; &quot;conversion ctor: a = &quot; &lt;&lt; m_a &lt;&lt; &quot;\n&quot;;
	}

	foo(foo const&amp; other)
	{
		m_a = other.m_a;
		std::cout &lt;&lt; &quot;copy ctor: a = &quot; &lt;&lt; m_a &lt;&lt; &quot;\n&quot;;
	}

	void use()
	{
		std::cout &lt;&lt; &quot;use: a = &quot; &lt;&lt; m_a &lt;&lt; &quot;\n&quot;;
	}

	void main_checkpoint()
	{
		std::cout &lt;&lt; &quot;main checkpoint: a = &quot; &lt;&lt; m_a &lt;&lt; &quot;\n&quot;;
	}
};

foo test_implicit()
{
	return &quot;implicit conversion&quot;;
}

foo test_explicit()
{
	return foo(&quot;explicit conversion&quot;);
}

foo test_named_value()
{
	foo f(&quot;named return value&quot;);
	return f;
}

foo test_named_used_value()
{
	foo f(&quot;named &amp; used return value&quot;);
	f.use();
	return f;
}

foo nested_direct_helper(char const* a)
{
	return foo(a);
}

foo nested_named_used_helper(char const* a)
{
	foo f(a);
	f.use();
	return f;
}

foo test_nested_direct()
{
	return nested_direct_helper(&quot;nested direct&quot;);
}

foo test_nested_named_used()
{
	return nested_named_used_helper(&quot;nested named used&quot;);
}

foo test_nested_2x_named_2x_used()
{
	foo f(nested_named_used_helper(&quot;nested 2x named 2x used&quot;));
	f.use();
	return f;
}

int main()
{
	{
		foo f(test_implicit());
		f.main_checkpoint();
		std::cout &lt;&lt; &quot;\n\n&quot;;
	}
	{
		foo f(test_explicit());
		f.main_checkpoint();
		std::cout &lt;&lt; &quot;\n\n&quot;;
	}
	{
		foo f(test_named_value());
		f.main_checkpoint();
		std::cout &lt;&lt; &quot;\n\n&quot;;
	}
	{
		foo f(test_named_used_value());
		f.main_checkpoint();
		std::cout &lt;&lt; &quot;\n\n&quot;;
	}
	{
		foo f(test_nested_direct());
		f.main_checkpoint();
		std::cout &lt;&lt; &quot;\n\n&quot;;
	}
	{
		foo f(test_nested_named_used());
		f.main_checkpoint();
		std::cout &lt;&lt; &quot;\n\n&quot;;
	}
	{
		foo f(test_nested_2x_named_2x_used());
		f.main_checkpoint();
		std::cout &lt;&lt; &quot;\n\n&quot;;
	}
}
</code></pre>
<p>Mit VC10 mit Debug Einstellungen compiliert:</p>
<pre><code>conversion ctor: a = implicit conversion
main checkpoint: a = implicit conversion

conversion ctor: a = explicit conversion
main checkpoint: a = explicit conversion

conversion ctor: a = named return value
copy ctor: a = named return value
main checkpoint: a = named return value

conversion ctor: a = named &amp; used return value
use: a = named &amp; used return value
copy ctor: a = named &amp; used return value
main checkpoint: a = named &amp; used return value

conversion ctor: a = nested direct
main checkpoint: a = nested direct

conversion ctor: a = nested named used
use: a = nested named used
copy ctor: a = nested named used
main checkpoint: a = nested named used

conversion ctor: a = nested 2x named 2x used
use: a = nested 2x named 2x used
copy ctor: a = nested 2x named 2x used
use: a = nested 2x named 2x used
copy ctor: a = nested 2x named 2x used
main checkpoint: a = nested 2x named 2x used
</code></pre>
<p>Hier wird also noch ein paar mal der Copy-Ctor aufgerufen. Bei den ganz einfachen Beispielen &quot;fehlt&quot; er allerdings schon.</p>
<p>Mit Release Einstellungen sieht es dann so aus:</p>
<pre><code>conversion ctor: a = implicit conversion
main checkpoint: a = implicit conversion

conversion ctor: a = explicit conversion
main checkpoint: a = explicit conversion

conversion ctor: a = named return value
main checkpoint: a = named return value

conversion ctor: a = named &amp; used return value
use: a = named &amp; used return value
main checkpoint: a = named &amp; used return value

conversion ctor: a = nested direct
main checkpoint: a = nested direct

conversion ctor: a = nested named used
use: a = nested named used
main checkpoint: a = nested named used

conversion ctor: a = nested 2x named 2x used
use: a = nested 2x named 2x used
use: a = nested 2x named 2x used
main checkpoint: a = nested 2x named 2x used
</code></pre>
<p>Wie man sieht wird hier kein einziges mal der Copy-Ctor aufgerufen. Alle Aufrufe wurden wegoptimiert.</p>
<p>Die Regeln die das ganze laut Standard erlauben nennen sich RVO (&quot;return value optimization&quot;) und NRVO (&quot;named return value optimization&quot;).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1902540</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1902540</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 25 May 2010 22:55:39 GMT</pubDate></item><item><title><![CDATA[Reply to [gelöst]Unterschied Typumwandlungskonstrutor zu Allgemeinen Konstruktor on Tue, 25 May 2010 23:12:21 GMT]]></title><description><![CDATA[<p>p.S.: vielleicht hab ich auch deine Frage falsch verstanden.</p>
<p>hibbes schrieb:</p>
<blockquote>
<pre><code class="language-cpp">return 1; // calls A: nicht doch C weil copy und default hier eins sind?
</code></pre>
</blockquote>
<p>Da steht 1 (eins), und das ist ein Integer-Literal (eine Konstante).<br />
Da ein Integer kein &quot;foo&quot; ist, muss irgendwie konvertiert werden, und das kann nur der Konvertierungskonstruktor &quot;A&quot;.</p>
<p>Es darf danach zusätzlich der Copy-Ctor &quot;C&quot; aufgerufen werden, muss aber nicht. Und wird in so einfachen Fällen meist auch nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1902542</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1902542</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 25 May 2010 23:12:21 GMT</pubDate></item><item><title><![CDATA[Reply to [gelöst]Unterschied Typumwandlungskonstrutor zu Allgemeinen Konstruktor on Wed, 26 May 2010 06:27:23 GMT]]></title><description><![CDATA[<p>Vielen vielen lieben Dank,<br />
da hast du dir ja echt Mühe gegeben einem C++ Anfänger was zu erklären. Das bei dem <strong>return 1</strong> ja einen Typumwandlung stattfindet hatte ich bei meiner Frage nicht bedacht und nun macht dein Beispiel auch Sinn.</p>
<p>Ich denke deine anschaulichen Beispiele werden auch Anderen eine große Hilfe sein, danke nochmal. Du solltest C++ Dozent werden <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>G hibbes</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1902558</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1902558</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Wed, 26 May 2010 06:27:23 GMT</pubDate></item></channel></rss>