<?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[C++11 vtbl, inline und final]]></title><description><![CDATA[<p>Hi,</p>
<p>bisher habe ich die Definition jeder auch noch so kurzen virtuellen Methode nicht in den Header geschrieben, da Inlining ja nicht möglich ist. In C++11 kann ich jetzt allerdings eine Klasse mit einem <code>final</code> versehen um zu verhindern, dass irgendjemand auf die Idee kommt, Erben zu wollen. Wenn man jetzt eine virtuelle Methode einer finalen Klasse aufruft, die im Header definiert ist, weiß der Compiler doch, welche Definition er aufrufen muss. Das Inlining sollte in diesem Fall wieder möglich sein. Ein Beispiel:</p>
<pre><code class="language-cpp">struct Animal {
	virtual int weight() const = 0;	
};

struct Pig : public Animal {
	int weight() const override
	{ return 100; }
};

// Final
struct Bird : public Animal final {
	int weight() const override
	{ return 1; }
};

int calcShippingPrice(const Pig&amp; pig, int dperkg) {
	// Kein inlining möglich
	return pig.weight() * dperkg;
}

int calcShippingPrice(const Bird&amp; bird, int dperkg) {
	// Inlining möglich?
	return bird.weight() * dperkg;
}
</code></pre>
<p>Und nicht nur final-Klassen sollten inline-taugliche virtuelle Methoden im Header definieren, da vielleicht eine final-Klasse von ihr erbt und die Methode nicht überschreibt. Nur dann ist wieder Inlining möglich:</p>
<pre><code class="language-cpp">struct Animal {
	virtual int weight() const
	{ return 10; }
};

// Final - übernimmt Definition von Animal
struct Pig final { };

int calcShippingPrice(const Pig&amp; pig, int dperkg) {
	// Inlining möglich
	return pig.weight() * dperkg;
}
</code></pre>
<p>Stimmt meine Theorie?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/300783/c-11-vtbl-inline-und-final</link><generator>RSS for Node</generator><lastBuildDate>Wed, 12 Aug 2026 15:30:02 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/300783.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 10 Mar 2012 17:39:41 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to C++11 vtbl, inline und final on Sat, 10 Mar 2012 17:39:41 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>bisher habe ich die Definition jeder auch noch so kurzen virtuellen Methode nicht in den Header geschrieben, da Inlining ja nicht möglich ist. In C++11 kann ich jetzt allerdings eine Klasse mit einem <code>final</code> versehen um zu verhindern, dass irgendjemand auf die Idee kommt, Erben zu wollen. Wenn man jetzt eine virtuelle Methode einer finalen Klasse aufruft, die im Header definiert ist, weiß der Compiler doch, welche Definition er aufrufen muss. Das Inlining sollte in diesem Fall wieder möglich sein. Ein Beispiel:</p>
<pre><code class="language-cpp">struct Animal {
	virtual int weight() const = 0;	
};

struct Pig : public Animal {
	int weight() const override
	{ return 100; }
};

// Final
struct Bird : public Animal final {
	int weight() const override
	{ return 1; }
};

int calcShippingPrice(const Pig&amp; pig, int dperkg) {
	// Kein inlining möglich
	return pig.weight() * dperkg;
}

int calcShippingPrice(const Bird&amp; bird, int dperkg) {
	// Inlining möglich?
	return bird.weight() * dperkg;
}
</code></pre>
<p>Und nicht nur final-Klassen sollten inline-taugliche virtuelle Methoden im Header definieren, da vielleicht eine final-Klasse von ihr erbt und die Methode nicht überschreibt. Nur dann ist wieder Inlining möglich:</p>
<pre><code class="language-cpp">struct Animal {
	virtual int weight() const
	{ return 10; }
};

// Final - übernimmt Definition von Animal
struct Pig final { };

int calcShippingPrice(const Pig&amp; pig, int dperkg) {
	// Inlining möglich
	return pig.weight() * dperkg;
}
</code></pre>
<p>Stimmt meine Theorie?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2190509</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2190509</guid><dc:creator><![CDATA[vptr]]></dc:creator><pubDate>Sat, 10 Mar 2012 17:39:41 GMT</pubDate></item><item><title><![CDATA[Reply to C++11 vtbl, inline und final on Sat, 10 Mar 2012 18:04:40 GMT]]></title><description><![CDATA[<p>Eine kleine Berichtigung:<br />
Im ersten Beispiel ist das final beim Bird verrutscht. Diese Zeile soll so sein:</p>
<pre><code class="language-cpp">struct Bird final : public Animal {
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2190512</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2190512</guid><dc:creator><![CDATA[vptr]]></dc:creator><pubDate>Sat, 10 Mar 2012 18:04:40 GMT</pubDate></item><item><title><![CDATA[Reply to C++11 vtbl, inline und final on Sat, 10 Mar 2012 18:50:14 GMT]]></title><description><![CDATA[<blockquote>
<p>da Inlining ja nicht möglich ist.</p>
</blockquote>
<p>Stimmt so nicht. vtable kommt erst ins Spiel, wenn der Typ dynamisch ist, also zur Compilezeit noch nicht feststeht. Statisches Binding geht natürelich trotz virtual weiterhin:</p>
<pre><code class="language-cpp">Test t;
t.foo();
</code></pre>
<p>t ist zur Compilezeit bekannt, foo könnte also problemlos geinlined werden, auch wenn es virtual wäre.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2190517</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2190517</guid><dc:creator><![CDATA[arghonaut]]></dc:creator><pubDate>Sat, 10 Mar 2012 18:50:14 GMT</pubDate></item><item><title><![CDATA[Reply to C++11 vtbl, inline und final on Sat, 10 Mar 2012 21:56:58 GMT]]></title><description><![CDATA[<p>Aber woher soll denn calcShippingPrice für Pigs wissen, ob es nicht von einer Klasse aufgerufen worden ist, die von Pig geerbt hat? Der Typ ist in dem Fall dynamisch und Inlining nicht möglich.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2190548</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2190548</guid><dc:creator><![CDATA[vptr]]></dc:creator><pubDate>Sat, 10 Mar 2012 21:56:58 GMT</pubDate></item><item><title><![CDATA[Reply to C++11 vtbl, inline und final on Sat, 10 Mar 2012 22:07:10 GMT]]></title><description><![CDATA[<p>Ich denke prinzipiell stimmt deine Theorie. Allerdings ist da nur die Frage ob es ein Compiler auch macht. Ist, denke ich, nicht so schwer (im Vergleich mit anderem Zeugs). Also kann es durchaus sein, dass es implementiert wird.</p>
<p>Allerdings könnte man inlineing auch für dynamische Typen machen. Zumindest für manche Fälle. Mit Data Flow Analysis könnte man da wahrscheinlich bereits viele herkömmliche Konstrukte dennoch inlinen (weil nicht komplett dynamisch).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2190551</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2190551</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Sat, 10 Mar 2012 22:07:10 GMT</pubDate></item><item><title><![CDATA[Reply to C++11 vtbl, inline und final on Sun, 11 Mar 2012 01:54:05 GMT]]></title><description><![CDATA[<p>Der Compiler kann bei dynamischen Typen kein Inlining machen, ohne den ganzen Code zu kennen. Schliesslich kann man in der hintersten Ecke des Codes eine Klasse ableiten, welche die Funktion überschreibt.</p>
<p>drakon schrieb:</p>
<blockquote>
<p>prinzipiell ... Allerdings ... denke ich ... kann es durchaus sein ... Allerdings könnte ... Zumindest ... könnte ... wahrscheinlich</p>
</blockquote>
<p>Da lehnst du dich aber gerade etwas aus dem Fenster <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2190572</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2190572</guid><dc:creator><![CDATA[Finaliz0r]]></dc:creator><pubDate>Sun, 11 Mar 2012 01:54:05 GMT</pubDate></item><item><title><![CDATA[Reply to C++11 vtbl, inline und final on Sun, 11 Mar 2012 11:25:30 GMT]]></title><description><![CDATA[<p>Finaliz0r schrieb:</p>
<blockquote>
<p>drakon schrieb:</p>
<blockquote>
<p>prinzipiell ... Allerdings ... denke ich ... kann es durchaus sein ... Allerdings könnte ... Zumindest ... könnte ... wahrscheinlich</p>
</blockquote>
<p>Da lehnst du dich aber gerade etwas aus dem Fenster <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
</blockquote>
<p>Nein. Es geht darum, dass es möglich ist. Ob ein Compiler das macht ist eine andere Frage. Ich weiss nicht ob es gängige Compiler machen, aber ich weiss, dass es ginge. <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="😉"
    /><br />
Nicht immer, da stimme ich dir zu, aber in einigen Fällen.</p>
<pre><code class="language-cpp">Animal a = 0;
if(...) a = new Pig(1);
else a = new Pig(2);

a.weight();
</code></pre>
<p>Wäre z.B ein Fall welchen man ganz gut finden kann.</p>
<p>Ich bin in meinen Aussagen nur eher vorsichtig, wenn ich nicht 100% weiss, dass es geht. Ich behaupte nicht einfach so ins blaue hinaus, wie es einige tun. <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2190610</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2190610</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Sun, 11 Mar 2012 11:25:30 GMT</pubDate></item><item><title><![CDATA[Reply to C++11 vtbl, inline und final on Sun, 11 Mar 2012 11:37:30 GMT]]></title><description><![CDATA[<p>vptr schrieb:</p>
<blockquote>
<p>Aber woher soll denn calcShippingPrice für Pigs wissen, ob es nicht von einer Klasse aufgerufen worden ist, die von Pig geerbt hat? Der Typ ist in dem Fall dynamisch und Inlining nicht möglich.</p>
</blockquote>
<p>der gcc inlined mir solche Fälle problemlos. Sogar beo folgender Signatur wird weight() inline, sofern der Compiler irgendwie aus dem umliegenden Code erschließen kann, dass der Typ fix ist.</p>
<pre><code class="language-cpp">int calcShippingPrice(const Animal&amp; pig, int dperkg)
</code></pre>
<p>War echt ärgerlich, als ich eine solche Funktion profilen wollte, die dann aber im optimierten Code gar nicht mehr vorkam...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2190615</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2190615</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Sun, 11 Mar 2012 11:37:30 GMT</pubDate></item><item><title><![CDATA[Reply to C++11 vtbl, inline und final on Tue, 13 Mar 2012 10:38:22 GMT]]></title><description><![CDATA[<p>vptr schrieb:</p>
<blockquote>
<p>[...]</p>
<pre><code class="language-cpp">[...]
struct Animal {
    virtual int weight() const
    { return 10; }
};

struct Bird final : public Animal {
	int weight() const override
	{ return 1; }
};

int calcShippingPrice(const Bird&amp; bird, int dperkg) {
	// Inlining möglich?
	return bird.weight() * dperkg;
}
</code></pre>
</blockquote>
<p>In einem Programm, was an dieser Stelle kein undefiniertes Verhalten hervorruft, kann .weight in diesem Fall ja nur .Bird::weight sein. Deswegen wäre es völlig legal für einen Compiler, hier auch zu inlinen und die return-Zeile zu &quot;return dperkg;&quot; optimieren. Vor undefiniertem Verhalten muss er sich ja nicht extra schützen.</p>
<p>meine zwei Eurocents,<br />
kk</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2191137</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2191137</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Tue, 13 Mar 2012 10:38:22 GMT</pubDate></item></channel></rss>