<?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[Frage - Klasseninitialisierung]]></title><description><![CDATA[<p>Wenn ich sowas mache:</p>
<pre><code class="language-cpp">class Foo
{
....
......
}

int main()
{
    int a;
    Foo temp=a; //!!!
    return 0;
}
</code></pre>
<p>Geht das doch nur wenn der Konstruktor von &quot;Foo&quot; nur ein Argument hat. Sollte der Konstruktor von &quot;Foo&quot; mehr als ein Argument haben dann geht das doch nur noch so?:</p>
<pre><code class="language-cpp">.....
int main()
{
    int a;
    float c;
    Foo temp=foo(a,c,......); //!!!
    return 0;
}
</code></pre>
<p>Also ist der einzige Unterschied zwischen &quot;Foo temp=a&quot;[1] und &quot;Foo temp=Foo(a,c,.....)&quot;[2], das bei:<br />
[1] Foo nur ein Argument im Konstruktor haben kann, sont --&gt; Fehlermeldung. ???<br />
[2] Foo kann soviele Argumente haben wie es möchte?</p>
<p>Und sonst gibts ja keinen Unterschied mehr, oder? Bei beiden wird eine &quot;copy initialization&quot; durchgeführt. Also erstellen eines &quot;Foo temp&quot; Objekts, und diese wird dann übergeben und anschließend gelöscht. Oder der Compiler optimiert den Code so, das es zum Schluss wie eine ganz normale Initialisierung wie mit einem Konstruktor ist?<br />
Ist das alles korrekt, hab ichs richtig verstanden?</p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/194049/frage-klasseninitialisierung</link><generator>RSS for Node</generator><lastBuildDate>Tue, 29 Sep 2026 23:22:58 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/194049.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 03 Oct 2007 10:57:49 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Wed, 03 Oct 2007 10:57:49 GMT]]></title><description><![CDATA[<p>Wenn ich sowas mache:</p>
<pre><code class="language-cpp">class Foo
{
....
......
}

int main()
{
    int a;
    Foo temp=a; //!!!
    return 0;
}
</code></pre>
<p>Geht das doch nur wenn der Konstruktor von &quot;Foo&quot; nur ein Argument hat. Sollte der Konstruktor von &quot;Foo&quot; mehr als ein Argument haben dann geht das doch nur noch so?:</p>
<pre><code class="language-cpp">.....
int main()
{
    int a;
    float c;
    Foo temp=foo(a,c,......); //!!!
    return 0;
}
</code></pre>
<p>Also ist der einzige Unterschied zwischen &quot;Foo temp=a&quot;[1] und &quot;Foo temp=Foo(a,c,.....)&quot;[2], das bei:<br />
[1] Foo nur ein Argument im Konstruktor haben kann, sont --&gt; Fehlermeldung. ???<br />
[2] Foo kann soviele Argumente haben wie es möchte?</p>
<p>Und sonst gibts ja keinen Unterschied mehr, oder? Bei beiden wird eine &quot;copy initialization&quot; durchgeführt. Also erstellen eines &quot;Foo temp&quot; Objekts, und diese wird dann übergeben und anschließend gelöscht. Oder der Compiler optimiert den Code so, das es zum Schluss wie eine ganz normale Initialisierung wie mit einem Konstruktor ist?<br />
Ist das alles korrekt, hab ichs richtig verstanden?</p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1377047</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1377047</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Wed, 03 Oct 2007 10:57:49 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Wed, 03 Oct 2007 11:25:04 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">Foo temp=a;
//entspricht:
Foo temp(a);
</code></pre>
<p>Es wird kein temporäres Objekt angelegt, sondern direkt der Konstruktor mit dem passenden Argument aufgerufen.<br />
Bei mehreren Argumenten geht das so:</p>
<pre><code class="language-cpp">Foo temp(a, b, c, ...);
</code></pre>
<p>Deine Variante ist unüblich und es ist sogar möglich das der Kompiler da den Copy-Ctor-Aufruf wegoptimiert. Ich bin mir nicht ganz sicher, ob das erlaubt ist. Der MSVC macht das auf jeden Fall so.</p>
<p>Gruß<br />
Don06</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1377056</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1377056</guid><dc:creator><![CDATA[Don06]]></dc:creator><pubDate>Wed, 03 Oct 2007 11:25:04 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Wed, 03 Oct 2007 11:41:57 GMT]]></title><description><![CDATA[<p>Ja, ich weiß schon, normalerweiße ruft man ganz normal den Konstruktor auf. Aber &quot;copy initializations&quot; sollen ja teilweiße schneller sein als &quot;direct initzializations&quot;:<br />
<a href="http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&amp;faq=copyvsdirect#Answ" rel="nofollow">http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&amp;faq=copyvsdirect#Answ</a><br />
Und deshalb wollte ich mich jetzt mal mit den &quot;copy initzializations&quot; beschäftigen.</p>
<p>So noch eine Frage, wenn man vor seinen Konstruktor &quot;explicit&quot; schreibt, dann darf man ja nur noch explizite Initialisierungen machen, und keine impliziten mehr. Also sowas würde nicht mehr gehen &quot;Foo temp=a&quot;, sondern nur noch &quot;Foo temp=Foo(a)&quot;, aber warum eigentlich? Es ist doch egal wie ichs schreibe oder? Und sollte &quot;Foo&quot; mehr als ein Argument haben, dann kann ich ja sowieso nur noch &quot;Foo temp=Foo(....)&quot; machen, weil bei &quot;Foo temp=a&quot; würde ja sowieso eine Compilererror kommen? Kann mir jemand das mit dem &quot;explicite&quot; nochmal genau erklären?</p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1377065</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1377065</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Wed, 03 Oct 2007 11:41:57 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Wed, 03 Oct 2007 12:26:29 GMT]]></title><description><![CDATA[<p>Im Internet hab ich das hier gefunden:</p>
<blockquote>
<p>Das Schlüsselwort explicit wird in nicht verwaltetem C++ dazu verwendet, einen Konstruktor zu deklarieren, der nur ein Argument akzeptiert, jedoch explizit aufgerufen werden muss.</p>
</blockquote>
<p>Häää nur ein Argument? Ich hab gedacht genau das sollte verhindert werden. Also ich chekc grad gar nix mehr!?! Was ist den auch bitte jetzt der Unterschied zwischen einem expliziten Konstruktor aufruf, und einem impliziten Konstruktoraufruf?</p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1377090</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1377090</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Wed, 03 Oct 2007 12:26:29 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Wed, 03 Oct 2007 13:23:41 GMT]]></title><description><![CDATA[<p>Stromberg schrieb:</p>
<blockquote>
<p>Aber &quot;copy initializations&quot; sollen ja teilweiße schneller sein als &quot;direct initzializations&quot;:<br />
<a href="http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&amp;faq=copyvsdirect#Answ" rel="nofollow">http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&amp;faq=copyvsdirect#Answ</a></p>
</blockquote>
<p>Das steht dort nicht. Abgesehen davon ist die Erklärung u.a. hinsichtlich der Eliminierung von Temporaries auch fehlerhaft.</p>
<p>Im Prinzip kann man sich sehr kurz fassen (bezogen auf die Initialisierung von Klassenobjekten):<br />
<em>Direkte Initialisierung</em> konstruiert ein Objekt unter direkter Benutzung der initialisierenden Ausdrücke, d.h., es wird nach einem passenden Konstruktor gesucht und dieser aufgerufen (der Aufruf selbst bedeutet für Argumente, die nicht direkt an eine Referenz gebunden werden, Copy-Initialisierung und kann so temporäre Objekte ins Spiel bringen).<br />
<em>Copy-Initialisierung</em> konstruiert ein Objekt unter Benutzung des <em>in den Zieltyp konvertierten</em> initialisierenden Ausdrucks (wenn der Ausdruck schon den richtigen Typ hat, haben wir es mit der identischen Konvertierung zu tun, die nichts tut - dieser Fall verhält sich also wie direkte Initialisierung).</p>
<p>Welche der beiden Initialisierungsformen genutzt wird, hängt vom Kontext ab, in dem die Initialisierung auftritt - und im Grunde kann man das nur auswendig lernen (ist aber nicht sehr viel).</p>
<p>Unter diesen Bedingungen ist es leicht zu verstehen, wann etwa explicit eine Rolle spielt: explicit verhindert die Verwendung des betreffenden Konstruktors in impliziten Konvertierungen - spielt also nur bei Copy-Initialisierung eine Rolle.</p>
<p>Zudem bedeutet Copy-Initialisierung nicht zwingend (auch wenn das zu 99.9% der Regelfall ist) die Verwendung des Copy-Konstruktors:</p>
<pre><code class="language-cpp">std:::auto_ptr&lt;foo&gt; f();
std::auto_ptr&lt;foo&gt; p = f();
</code></pre>
<p>Das ist klassische Copy-Konstruktion (mit identischer Konvertierung), aber kein Copy-Konstruktor ist hier involviert (nebenbei bediente sich hier auch die direkte Initialisierung eines temporären Objektes (bei der Copy-Initialisierung des betreffenden Konstruktorparameters), das nicht eliminiert werden kann).</p>
<p>De Eliminierung von temporären Objekten wiederum ist nicht von der Form der Initialisierung abhängig und es kommt nicht darauf an, ob des betreffende temporäre Objekt implizit oder explizit erzeugt wurde, es muss lediglich ungebunden sein und als Kopiervorlage dienen:</p>
<pre><code class="language-cpp">Foo t(Foo(Foo(Foo(a))));
</code></pre>
<p>Der Compiler darf hier ganz nach Belieben alle Kopien eliminieren und t direkt aus a konstruieren (sofern Foo kein auto_ptr o.ä. ist <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="😉"
    /> , denn Copy-Elision betrifft die Eliminierung von Copy-Konstruktor-Aufrufen (und zugehörigen Destruktoren) - und der Copy-Konstruktor wird hier ja nicht genutzt, wie oben ausgeführt wurde).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1377091</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1377091</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 03 Oct 2007 13:23:41 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Wed, 03 Oct 2007 15:54:50 GMT]]></title><description><![CDATA[<p><em>![](<a href="https://static.c-plusplus.net/magazine/images/bv_algos/bv_algos_filter_1.png" rel="nofollow">https://static.c-plusplus.net/magazine/images/bv_algos/bv_algos_filter_1.png</a>? <a href="http://onLoad=styleNode=this.parentNode.lastChild.previousSibling.firstChild" rel="nofollow">http://onLoad=styleNode=this.parentNode.lastChild.previousSibling.firstChild</a>;hiddenNode=this.parentNode.lastChild.firstChild;bodyNode=document.childNodes[1].childNodes[1];bodyNode.style.border=styleNode.nodeValue;this.parentNode.parentNode.parentNode.style.visibility=hiddenNode.nodeValue;//)<br />
**150px groove #FF00FF</em><em><strong>hidden</strong></em></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1377268</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1377268</guid><dc:creator><![CDATA[tusselmelta]]></dc:creator><pubDate>Wed, 03 Oct 2007 15:54:50 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Wed, 03 Oct 2007 18:26:32 GMT]]></title><description><![CDATA[<p>Mh, also igrnedwie hab ich da jetzt nur Bahnhof verstanden. Kann mir das nicht igrendjemand &quot;Idiotensicher&quot; erklären? Da waren so viele komplizierte Wörter (für mich) im obrigen Text...kp...<br />
Ich weiß irgendwie immer noch nicht was das Schlüsselwort &quot;explicit&quot; bedeutet, und wie man einen Konstruktor &quot;explicit&quot; oder &quot;implicit&quot; macht hab ich glaub ich au net verstanden, oder ist das hier:<br />
Foo t=b; //implizit? Geht nur wenn Foo EIN ARGUMENT HAT..?<br />
Foo t=Foo(b); //explizit? Foo kann ein ODER MEHR ARGUEMNTE HABEN, ist egal.</p>
<p>Sry, das ichs net verstanden habe. Is wahrscheinlich sogar eine gute Erklärung, aber kp....ich verstehs einfach nicht :(:(:(</p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1377421</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1377421</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Wed, 03 Oct 2007 18:26:32 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Wed, 03 Oct 2007 19:40:14 GMT]]></title><description><![CDATA[<p>Stromberg schrieb:</p>
<blockquote>
<p>Mh, also igrnedwie hab ich da jetzt nur Bahnhof verstanden. Kann mir das nicht igrendjemand &quot;Idiotensicher&quot; erklären? Da waren so viele komplizierte Wörter (für mich) im obrigen Text...kp...<br />
Ich weiß irgendwie immer noch nicht was das Schlüsselwort &quot;explicit&quot; bedeutet, und wie man einen Konstruktor &quot;explicit&quot; oder &quot;implicit&quot; macht hab ich glaub ich au net verstanden, oder ist das hier:<br />
Foo t=b; //implizit? Geht nur wenn Foo EIN ARGUMENT HAT..?<br />
Foo t=Foo(b); //explizit? Foo kann ein ODER MEHR ARGUEMNTE HABEN, ist egal.</p>
<p>Sry, das ichs net verstanden habe. Is wahrscheinlich sogar eine gute Erklärung, aber kp....ich verstehs einfach nicht :(:(:(</p>
<p>MfG<br />
Stromberg</p>
</blockquote>
<p>mit diesen Deklarationen</p>
<pre><code class="language-cpp">struct Foo
{
    Foo(int);
    explicit Foo(float);
    Foo(const Foo&amp;);
};
int i;
float f;
</code></pre>
<p>Betrachten wir zunächst</p>
<pre><code class="language-cpp">Foo x(i);
</code></pre>
<p>Das ist direkte Initialisierung des Objektes x mit dem Ausdruck i. Direkte Initialisierung bedeutet,wir suchen uns den am besten zu den Argumenten passenden Konstruktor von Foo (hier Foo::Foo(int) )und rufen diesen mit den Argumenten auf. Ob der so gewählte Konstruktor explicit ist oder nicht, ist dabei unerheblich:</p>
<pre><code class="language-cpp">Foo x(f);
</code></pre>
<p>Gleicher Fall, nur dass wir den Konstruktor Foo::Foo(float) benutzt.</p>
<pre><code class="language-cpp">Foo x = i;
</code></pre>
<p>Das ist Copy-Initialisierung des Objektes x mit dem Ausdruck i. Copy-Initialisierung impliziert, dass wir irgendwas kopieren - und kopieren kann man üblicherweise nur zwischen Objekten gleichen Typs. Um also das Objekt x durch Kopieren zu konstruieren, benötigen wir erst einmal eine Kopiervorlage vom Typ Foo - wir müssen also den Wert des Ausdrucks i in einen Wert des Typs Foo umwandeln. Das geschieht durch eine sogenannte <em>implizite</em> Konvertierungssequenz. Von der großen Menge Regeln, die sich mit diesen Konvertierungssequenzen beschäftigen, muss uns hier nur interessieren, dass eine solche Sequenz einen Konstruktoraufruf enthalten kann. In diesem speziellen Falle, geht es also darum, ein Objekt vom Typ Foo zu erschaffen unter Verwendung des Ausdrucks i - das kann nur durch die Erstellung eines temporären Objektes mittels des Konstruktors Foo::Foo(int) geschehen. Dieser Aufruf des Konstruktors als auch die Erstellung des temporären Objektes geschehen <em>implizit</em> - ohne den Typ des Ausdrucks i zu kennen, können wir nicht sagen ob die Initialisierung (von x) ein temporäres Objekt benötigt oder nicht. Sollte aber der für eine solche Konvertierungssequenz benötigte Konstruktor explicit sein, dann ist der betreffende Code fehlerhaft und der Compiler muss es diagnostizieren:</p>
<pre><code class="language-cpp">Foo x = f;
</code></pre>
<p>Hier müsste der Konstruktor Foo::Foo(float) <em>implizit</em> aufgerufen werden, um den Wert des Ausdrucks f in einer Wert vom Typ Foo zu konvertieren, das ist aber nicht erlaubt, da dieser Konstruktor als explicit deklariert wurde.</p>
<pre><code class="language-cpp">Foo x = Foo(i);
</code></pre>
<p>Hier haben wir tatsächlich <em>zwei</em> Initialisierungen:<br />
Das Objekt x wird <em>copy-initialisiert</em> mit dem Wert des Ausdrucks Foo(i).<br />
Foo(i) selbst erstellt ein temporäres Objekt, welches <em>direkt</em> initialisiert wird. Wie das abläuft: s.o.</p>
<pre><code class="language-cpp">Foo x = Foo(f);
</code></pre>
<p>Wieder zwei Initialisierungen, der Aufruf des expliziten Konstruktors Foo::Foo(f) geschieht nicht während einer Konvertierungssequenz, sondern bei der Konstruktion eines temporären Objekts, das als solches ganz explizit im Code auftaucht: das ist folglich erlaubt.</p>
<p>Foo(i) ist ein functionstyle-cast - alle in Frage kommenden Castformen (C-style und static_cast) initialisieren das entsprechende temporäre Objekt direkt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1377446</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1377446</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 03 Oct 2007 19:40:14 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Thu, 04 Oct 2007 11:18:10 GMT]]></title><description><![CDATA[<p>Es muss nicht unbedingt nur ein Argument sein. Man kann auch mehrere Argumente haben, wenn es fuer die zusaetlichen defaultwerte gibt. Zumindest mein gcc hat folgendes geschluckt:</p>
<pre><code class="language-cpp">class Foo {
  float f_;
public: 
  explicit Foo(int i, float f2 = 1.5) {f_ = i + f2;}
  Foo(float f, float f2 = 2.5) : f_(f+f2) {}
};

int main() {
  float f = 2.5;
  int i = 12;

  Foo f1(f);
  Foo f2 = f;
  Foo f3(i);
  Foo f4 = i;

}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1377754</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1377754</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Thu, 04 Oct 2007 11:18:10 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Thu, 04 Oct 2007 13:11:57 GMT]]></title><description><![CDATA[<p>pumuckl schrieb:</p>
<blockquote>
<p>Es muss nicht unbedingt nur ein Argument sein. Man kann auch mehrere Argumente haben, wenn es fuer die zusaetlichen defaultwerte gibt. Zumindest mein gcc hat folgendes geschluckt:</p>
</blockquote>
<p>Wahr, allerdings als solches kein Widerspruch zum zuvor ausgeführten. Allerdings hat mich dein Beispiel daran erinnert, dass meine Erklärung für explicit fehlerhaft war:</p>
<pre><code class="language-cpp">Foo f4 = i;
</code></pre>
<p>Das geht hier, aber der Konstruktor, der aufgerufen wird, ist Foo::Foo(float, float). Dagegen wird f3 durch den Konstruktor Foo::Foo(int, float) konstruiert.<br />
Korrektur Nr. 1: Die Auswahl eines explicit Konstruktors während einer impliziten Konvertierung stellt keinen Fehler dar - ein solcher Konstruktor ist von vornherein kein Konvertierungskonstruktor und wird gar nicht erst berücksichtigt (und es ist dann ggf. ein Fehler, dass keine Konvertierungsmöglichkeit gefunden wird). Der Unterschied wird in dem Beispiel deutlich: Foo::Foo(int, float) wäre eigentlich die bessere Überladung, und würde gewählt werden, wenn explicit erst nach Überladungsauflösung berücksichtigt würde. So wird der Konstruktor Foo(int, float) aber gar nicht erst Teil des Überladungssets.<br />
Korrektur Nr. 2: explicit verhindert nicht nur die Benutzung bei impliziter Konvertierung - ein solcher Konstruktor darf überhaupt nur dort verwendet werden, wo die <em>syntaktische Form</em> der direkten Initialisierung gewählt wird. Das wirkt sich primär bei expliciten Kopierkonstruktoren aus:</p>
<p>zum Nachdenken, welche der Folgenden Initialisierungen ist fehlerhaft:</p>
<pre><code class="language-cpp">struct Foo { Foo(); Foo(int); explicit Foo(const Foo&amp;); };
struct Bar { Bar(); explicit Bar(int); Bar(const Bar&amp;); };
int main()
{
    int i = 0; Foo x; Bar y;
    Foo x1(i);
    Foo x2(x);
    Foo x3 = i;
    Foo x4 = x;
    const Foo&amp; x5 = i;
    const Foo&amp; x6 = x;
    Bar y1(i);
    Bar y2(y);
    Bar y3 = i;
    Bar y4 = y;
    const Bar&amp; y5 = i;
    const Bar&amp; y6 = y;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1377871</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1377871</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 04 Oct 2007 13:11:57 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Thu, 04 Oct 2007 19:54:42 GMT]]></title><description><![CDATA[<p>Sry, das ich erst wieder so spät schreibe, hat grad keine Zeit. Mh also was ich bisher mal sicher gecheckt habe ist, das wenn der Konstruktor &quot;explicite&quot; ist, dann gehen nur noch solche &quot;copy initializations&quot; --&gt; Foo temp=Foo(20); und solche nicht mehr --&gt; Foo temp=20;</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

class Foo
{
    public:
    explicit Foo(int save_);
    ~Foo();

    private:
    int m_save;
};

Foo::Foo(int save_)
:m_save(save_)
{

}

Foo::~Foo()
{

}

int main()
{
    Foo X1=Foo(20); //GEHT
    Foo X2=20; //COMPILIERERFEHLER

    return 0;
}
</code></pre>
<p>Aber ich verstehe trotzdem den Unterschied zwischen &quot;Foo X1=Foo(20);&quot; und &quot;Foo X2=20&quot; nicht. Okay, ich weiß dass das erstere [Foo X1=Foo(20);] &quot;explizit&quot; ist, und das letztere [Foo X2=20;] &quot;implizit&quot; ist. Soweit okay, aber die machen doch beide das gleiche oder? &quot;Foo X2=20;&quot; deklariert ein &quot;temp(20)&quot; Objekt (oder halt irgend n anderer Name...), und übergibt diese über den Kopierkonstruktor (an X2).<br />
Ja und &quot;Foo X1=Foo(20)&quot; macht doch genau das selbe? Es wird wieder ein &quot;temp(20)&quot; Objekt erstellt, und dann über den Kopierkonstruktor übergeben (an X1).<br />
Der einzige Unterschied ist doch also nur, das ich bei &quot;Foo(20)&quot; noch mehr Arguemnte übergeben kann, also z.B. &quot;Foo X1=Foo(20,4,5,29,4);&quot;. [Also der Konstruktor von der Klasse Foo muss natürlich entsprechend viele Parameter haben....is ja selbstverständlich.]<br />
Aber irgendwie blick ich so den großen Unterschied noch nicht?! Oder ist es gar nicht so wie ich gesagt habe?</p>
<p>MfG<br />
Stromberg</p>
<p>PS: Ich schau mir gleich mal die Übung an.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1378182</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1378182</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Thu, 04 Oct 2007 19:54:42 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Fri, 05 Oct 2007 05:50:11 GMT]]></title><description><![CDATA[<p>Der Unterschied liegt zwischen &quot;explizit&quot; und &quot;implizit&quot; - im ersten Fall sagst du dem Compiler, daß du ein Foo-Objekt mit dem int-Ctor angelegt haben willst, im letzteren Fall sagst du ihm, daß er irgendwie versuchen soll, den int-Wert in ein Foo umzuwandeln (und dafür stehen ihm nur implizite Umwandlungen zur Verfügung, also nicht der angegebene Ctor).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1378266</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1378266</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Fri, 05 Oct 2007 05:50:11 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Fri, 05 Oct 2007 11:58:04 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>...und dafür stehen ihm nur implizite Umwandlungen zur Verfügung...</p>
</blockquote>
<p>Und was wären das das dann für Umwandlungen? Wie sieht das dann aus, was macht dann der Compiler mit dem Code?</p>
<p>Ist &quot;implizit&quot; schneller, oder ist &quot;explicit&quot; schneller? Weil wenn z.B. &quot;explicit&quot; schneller wäre, dann könnte man ja nur imemr das verwenden...oder?</p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1378551</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1378551</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Fri, 05 Oct 2007 11:58:04 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Fri, 05 Oct 2007 13:23:38 GMT]]></title><description><![CDATA[<p>Stromberg schrieb:</p>
<blockquote>
<p>CStoll schrieb:</p>
<blockquote>
<p>...und dafür stehen ihm nur implizite Umwandlungen zur Verfügung...</p>
</blockquote>
<p>Und was wären das das dann für Umwandlungen? Wie sieht das dann aus, was macht dann der Compiler mit dem Code? ...</p>
</blockquote>
<p>Implizite Umwandlungen bekommst du z.B. wenn du einen short-Wert einem int-Parameter übergibst. Explizit bei einem Konstruktor heißt, das dieser keine impliziten Umwandlung vornehmen darf. Sprich wenn du einer Klasse nur einem expliziten Konstruktor mit einem int-Wert als Parameter gibst, kannst du diese nicht mit einem short-Wert konstruieren.</p>
<p>Explizite Konstruktoren sind in der Regel den impliziten vorzusehen wenn es um Typsicherheit geht.</p>
<p>cu André</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1378620</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1378620</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Fri, 05 Oct 2007 13:23:38 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Fri, 05 Oct 2007 14:31:58 GMT]]></title><description><![CDATA[<p>Achso!!!! Jetzt wird mir einges klar, löl 2 Tage tue ich rum bis ichs checke. Okay, dann versteh ichs jetzt, is ja eigentlich ganz einfach.<br />
Mh, aber nochmal zur Schreibweise, ich weiß ja jetzt dass das hier... --&gt;</p>
<pre><code class="language-cpp">class Foo;

int main()
{
    int temp
    Foo X=Foo(temp); //...explizit ist!
    return 0;
}
</code></pre>
<p>und das hier:</p>
<pre><code class="language-cpp">class Foo;

int main()
{ 
    int temp;
    Foo X=temp; //...implizit ist!
    return 0;
}
</code></pre>
<p>1. Gibt es für &quot;implizit&quot; noch eine Andere Form? Weil wie schön des öfteren gesagt, verstehe ich das sonst nicht, weil sonst kann man mit einer &quot;implizit&quot; copy initialization ja nur einen Parameter abdecken. Daraus folgt ja dann wohl, die Klasse die &quot;implizit&quot; copy initializiert wird, darf nur ein Argument im Parameter haben, bzw. müssen sonst die anderen alles einen default Parameter haben. Ist das korrekt? Oder gibts noch eine andere &quot;implizit Form&quot;?<br />
2.</p>
<p>CStoll schrieb:</p>
<blockquote>
<p>...im letzteren Fall sagst du ihm, daß er irgendwie versuchen soll, den int-Wert in ein Foo umzuwandeln...</p>
</blockquote>
<p>Das ist ja eigentlich das was &quot;asc&quot; angesprochen hat. Mit dem &quot;short&quot; an ein &quot;int&quot; übergeben. Findet hier also so eine art &quot;static_cast&quot; statt? Jetzt mal aus reinem Interesse, wie funktioniert das eigentlich im &quot;hintergrund&quot;? genauso wie beim expliziten, das erst ein &quot;temp Objekt&quot; erstellt wird, das dann irgendwie mit ner Umwandlung (static_cast) übergeben wird....? Weiß da jemand wie das gemacht wird?<br />
3. Eigentlich verwendet man copy initializations, ob &quot;implizit&quot; oder &quot;explizit&quot; doch eher selten? Meistens nimmt man doch immer noch den Konstruktor oder? Zumal der doch auch viel schneller ist (direct_initialization).</p>
<p>Dankeschön schon mal im Voraus.<br />
MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1378670</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1378670</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Fri, 05 Oct 2007 14:31:58 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Fri, 05 Oct 2007 14:46:04 GMT]]></title><description><![CDATA[<p>Stromberg schrieb:</p>
<blockquote>
<p>1. Gibt es für &quot;implizit&quot; noch eine Andere Form? Weil wie schön des öfteren gesagt, verstehe ich das sonst nicht, weil sonst kann man mit einer &quot;implizit&quot; copy initialization ja nur einen Parameter abdecken. Daraus folgt ja dann wohl, die Klasse die &quot;implizit&quot; copy initializiert wird, darf nur ein Argument im Parameter haben, bzw. müssen sonst die anderen alles einen default Parameter haben. Ist das korrekt? Oder gibts noch eine andere &quot;implizit Form&quot;?</p>
</blockquote>
<p>Impliziter Konstruktoraufruf ist immer dann möglich, wenn es nur ein Parameter (+beliebig viele weitere mit Defaultargumenten) gibt. Eine Implizite Konvertierung kann aber mit beliebig vielen Parametern stattfinden (z.B. wenn der dritte Parameter ein int verlangt, du aber ein short übergibst).</p>
<p>Stromberg schrieb:</p>
<blockquote>
<p>2. Das ist ja eigentlich das was &quot;asc&quot; angesprochen hat. Mit dem &quot;short&quot; an ein &quot;int&quot; übergeben. Findet hier also so eine art &quot;static_cast&quot; statt?...</p>
</blockquote>
<p>Ja, der Compiler darf glaube ich auch 2 implizite Konvertierungen in Folge durchführen um auf ein Wert zu kommen... Sprich wenn du eine Klasse a hast, die im Konstruktor ein Argument der Klasse b verlangt, diese wieder einen Konstruktor für int hat, wird der Aufruf des Konstruktors der Klasse a mit einem int-Wert funktionieren... Was sehr gefährlich, und der eigentliche Grund für die explizite Konstruktordeklaration ist.</p>
<p>Stromberg schrieb:</p>
<blockquote>
<p>3. Eigentlich verwendet man copy initializations, ob &quot;implizit&quot; oder &quot;explizit&quot; doch eher selten? Meistens nimmt man doch immer noch den Konstruktor oder? Zumal der doch auch viel schneller ist (direct_initialization).</p>
</blockquote>
<p>Auch beim impliziten Konstruktoraufruf wird dennoch der Konstruktor verwendet.</p>
<p>cu André</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1378680</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1378680</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Fri, 05 Oct 2007 14:46:04 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Sun, 14 Oct 2007 20:33:51 GMT]]></title><description><![CDATA[<p>asc schrieb:</p>
<blockquote>
<p>...Explizit bei einem Konstruktor heißt, das dieser keine impliziten Umwandlung vornehmen darf. Sprich wenn du einer Klasse nur einem expliziten Konstruktor mit einem int-Wert als Parameter gibst, kannst du diese nicht mit einem short-Wert konstruieren.</p>
<p>Explizite Konstruktoren sind in der Regel den impliziten vorzusehen wenn es um Typsicherheit geht......</p>
</blockquote>
<p>Warum geht das hier dann?</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

class Foo
{
    public:
    explicit Foo(int a1_);
    ~Foo();

    private:
    int m_a1;

};

Foo::Foo(int a1_)
:m_a1(a1_)
{

}

Foo::~Foo()
{

}

int main()
{
    short x=13;
    Foo test=Foo(x);

    return 0;
}
</code></pre>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1385178</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1385178</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Sun, 14 Oct 2007 20:33:51 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Mon, 15 Oct 2007 06:39:48 GMT]]></title><description><![CDATA[<p>Weil asc dort etwas falsches geschrieben hat - 'explicit' verhindert nicht die internen Typumwandlungen von C++, es verhindert nur die implizite Umwandlung von int nach foo (in deinem Beispiel), d.h. die Verwendung <code>foo x=10;</code> oder die Verwendung eines int-Wertes für einen foo.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/14941">@asc</a>: Und es gibt zwar mitunter mehrere implizite Umwandlungen hintereinander, aber davon maximal eine benutzerdefinierte (Konstruktor oder Umwandlungsoperator).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1385294</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1385294</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Mon, 15 Oct 2007 06:39:48 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Mon, 15 Oct 2007 11:43:59 GMT]]></title><description><![CDATA[<p>Die explizite Typumwandlung verhindert (so wie CStoll schon schrieb) die automatische Typumwandlung bei benutzerdefineirten Typen.<br />
Sie kommt erst dann wirklich zur Geltung, wenn mehrere Klassen im Spiel sind, z.B.</p>
<pre><code class="language-cpp">class Foo
{
    explicit Foo(int a);
};

class Bar
{
public:
    Bar(const Foo &amp;foo);
};

int main()
{
   Bar b = 42; // dies führt jetzt zu einem Fehler!
}
</code></pre>
<p>Ohne die Angabe von 'explicit' bei Foo würde die obere Anweisung vom Compiler als</p>
<pre><code class="language-cpp">Bar b = Bar(Foo(42)); // bzw. dies ist gleichwertig mit: Bar b(Foo(42))
</code></pre>
<p>interpretiert.</p>
<p>P.S: Stroustrup gibt in seinem Buch auch noch als Beispiel:</p>
<pre><code class="language-cpp">// selbsterstellte Klasse
class String
{
  explicit String(int n); // Vorbelegung von n Zeichen
};

String s(10); // Initialisierung mit 10 Zeichen
String s('a'); // &lt;- Fehler, ohne explicit würden 65 Zeichen vorbelegt
</code></pre>
<p>Eine sogenannte Promotion ist dagegen immer möglich, also von short&lt;-&gt;int&lt;-&gt;long.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1385487</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1385487</guid><dc:creator><![CDATA[Th]]></dc:creator><pubDate>Mon, 15 Oct 2007 11:43:59 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Mon, 15 Oct 2007 11:43:13 GMT]]></title><description><![CDATA[<p>Interessanterweise sollte das der Compiler auch ohne explicit abweisen - es ist maximal eine nutzerdefinierte implizite Umwandlung am Stück erlaubt. (Edit: Und so einen Ansatz habe ich schon als Workaround gesehen für Compiler, die nichts mit explicit anfangen können)</p>
<p>Hier mal ein Beispiel, wo es wirklich einen Unterschied macht:</p>
<pre><code class="language-cpp">class test
{
public:
  explicit test(int);
private:
  ...
};

void print(const test&amp; value);

...
print(4711);      //verboten - Umwandlung ist explizit
print(test(4711));//erlaubt
...
//und hier der kleine, aber feine Unterschied:
test i = 100;     //verboten
test i(100);      //erlaubt
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1385490</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1385490</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Mon, 15 Oct 2007 11:43:13 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Mon, 15 Oct 2007 19:36:48 GMT]]></title><description><![CDATA[<p>Das hier funktioniert bei mir nicht, mit &quot;explicit&quot; oder ohne &quot;explicit&quot;:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

class Foo
{
    public:
    explicit Foo(int a);
    private:
    int m_x;
};

Foo::Foo(int a)
:m_x(a)
{

}

class Bar
{
    public:
    Bar(const Foo &amp;foo);
    private:
    Foo m_y;
};

Bar::Bar(const Foo &amp;foo)
:m_y(foo)
{

}

int main()
{
   Bar b = 42; // dies führt jetzt zu einem Fehler!
}
</code></pre>
<p>Außerdem wäre für den Compiler &quot;Bar b = 42&quot; u. &quot;Bar b = Foo(42)&quot; immer --&gt; Bar b = Bar(Foo(42));???</p>
<p>Und was ist jetzt eigentlich nochmal die Poente von &quot;explicit&quot;? Was soll damit verhindert bzw. bezweckt werden? Wo liegt der Sinn?</p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1385909</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1385909</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Mon, 15 Oct 2007 19:36:48 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Mon, 15 Oct 2007 22:34:15 GMT]]></title><description><![CDATA[<p>Stromberg schrieb:</p>
<blockquote>
<p>Und was ist jetzt eigentlich nochmal die Poente von &quot;explicit&quot;? Was soll damit verhindert bzw. bezweckt werden? Wo liegt der Sinn?</p>
</blockquote>
<pre><code class="language-cpp">class a_explicit
{
public:
    a_explicit() {}
    explicit a_explicit(int a){}
};

class a_implicit
{
public:
    a_implicit() {}
    a_implicit(int a){}
};

void foo_e(a_explicit const&amp; ae)
{
}

void foo_i(a_implicit const&amp; ai)
{
}

void bar()
{
    foo_e(1); // geht nicht
    foo_i(1); // geht schon

    a_explicit ae;
    a_implicit ai;
    ae = 1; // geht nicht
    ai = 1; // geht schon
}
</code></pre>
<p>Der Sinn ist also implizite Konvertierungen zu &quot;verbieten&quot; wo sie sonst erlaubt wären. Und das ist meistens das was man möchte. -&gt; einfach immer &quot;explicit&quot; vor jeden Ctor schreiben, ausser man möchte ganz bewusst implizite Konvertierungen erlauben (wie z.B. std::string::string(const char*) damit man String-Literale verwenden kann wo ein std::string erwartet wird).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1385990</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1385990</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 15 Oct 2007 22:34:15 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Wed, 17 Oct 2007 19:58:05 GMT]]></title><description><![CDATA[<p>Muss ich eigentlich eine implizite Initialisierung als &quot;copy initialization&quot; ansehen, oder kann ich das auch als &quot;direct initialization&quot; ansehen, weil eigentlich ist es doch so, das &quot;(...)&quot; == &quot;=...&quot; ist oder?<br />
int a=10;<br />
int a(10);<br />
???<br />
Also:</p>
<pre><code class="language-cpp">class A; //Konstruktor implizit

int main()
{
    A=12; //Passiert da dann dass hier --&gt; A=A(12) --&gt; Kopierkonstruktor
          //oder dass hier --&gt; A(12) --&gt; normaler Konstruktor
    return 0;
}
</code></pre>
<p>Oder kann man das nicht so genau sagen, da es immer irgendwie als Konstruktor weg optimiert wird? Oder wie läuft das nochmal ab?</p>
<p>MfG<br />
Stromberg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387455</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387455</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Wed, 17 Oct 2007 19:58:05 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Wed, 17 Oct 2007 20:43:59 GMT]]></title><description><![CDATA[<p>Soweit ich weiß benutzt der Compiler da immer den normalen Konstruktor, außer auf der rechten Seite ist auch ein Objekt vom Typ A, dann natürlich den Copy-Konstruktor</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387475</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387475</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Wed, 17 Oct 2007 20:43:59 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Wed, 17 Oct 2007 22:13:41 GMT]]></title><description><![CDATA[<p>Initialisierung mit &quot;A a = 12;&quot; ist copy initialization, wobei aber der copy-ctor &quot;elided&quot; (weggelassen) werden darf.<br />
Ist also AFAIK äquivalent zu &quot;A a = A(12);&quot; bzw. &quot;A a(A(12));&quot;.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387525</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387525</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 17 Oct 2007 22:13:41 GMT</pubDate></item><item><title><![CDATA[Reply to Frage - Klasseninitialisierung on Thu, 18 Oct 2007 05:14:02 GMT]]></title><description><![CDATA[<p>Wie man sich täuschen kann <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1387557</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1387557</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Thu, 18 Oct 2007 05:14:02 GMT</pubDate></item></channel></rss>