状況にもよりますが、通常、最適化を有効にしていれば、C バージョンよりも高価になることはありません。他の機能に本当に「お金を払う」のthis
は、継承と仮想関数を使用するときだけです。それ以外は、コンパイラは十分にスマートなので、this
使用していない関数で時間を無駄にすることはありません。次の点を考慮してください。
#include <iostream>
void globalDoStuff()
{
std::cout << "Hello world!\n";
}
struct Dummy
{
void doStuff() { callGlobalDoStuff(); }
void callGlobalDoStuff() { globalDoStuff(); }
};
int main()
{
globalDoStuff();
Dummy d;
d.doStuff();
}
GCC 最適化レベルO3
でコンパイルすると、次の逆アセンブルが得られます (余分なジャンクをカットして を表示するだけですmain()
)。
_main:
0000000100000dd0 pushq %rbp
0000000100000dd1 movq %rsp,%rbp
0000000100000dd4 pushq %r14
0000000100000dd6 pushq %rbx
0000000100000dd7 movq 0x0000025a(%rip),%rbx
0000000100000dde leaq 0x000000d1(%rip),%r14
0000000100000de5 movq %rbx,%rdi
0000000100000de8 movq %r14,%rsi
0000000100000deb callq 0x100000e62 # bypasses globalDoStuff() and just prints "Hello world!\n"
0000000100000df0 movq %rbx,%rdi
0000000100000df3 movq %r14,%rsi
0000000100000df6 callq 0x100000e62 # bypasses globalDoStuff() and just prints "Hello world!\n"
0000000100000dfb xorl %eax,%eax
0000000100000dfd popq %rbx
0000000100000dfe popq %r14
0000000100000e00 popq %rbp
0000000100000e01 ret
Dummy
との両方を完全に最適化globalDoStuff()
し、 の本体に置き換えただけであることに注意してくださいglobalDoStuff()
。globalDoStuff()
呼び出されることもありませんし、Dummy
構築されることもありません。代わりに、コンパイラ/オプティマイザはそのコードを 2 つのシステム コールに置き換えて、"Hello world!\n"
直接出力します。教訓は、コンパイラとオプティマイザは非常にスマートであり、一般的に、必要のないものにはお金を払わないということです。
一方、 のメンバー変数を操作するメンバー関数があるとしますDummy
。これには C 関数に比べてペナルティがあると思うかもしれませんね。C 関数は変更するオブジェクトへのポインターを必要とするため、おそらくそうではありませんthis
。
したがって、一般に、C++ では C と比較して追加料金を支払うことはありませんthis
。仮想関数には、呼び出す適切な関数を検索する必要があるため、(小さな) ペナルティがある可能性がありますが、ここで検討しているケースはそうではありません。
コンパイラで最適化をオンにしない場合、確かにペナルティが発生する可能性がありますが、なぜ最適化されていないコードを比較するのでしょうか?