次のコードを検討してください。
class cFoo {
private:
int m1;
char m2;
public:
int doSomething1();
int doSomething2();
int doSomething3();
}
class cBar {
private:
cFoo mFoo;
public:
cFoo getFoo(){ return mFoo; }
}
void some_function_in_the_callstack_hierarchy(cBar aBar) {
int test1 = aBar.getFoo().doSomething1();
int test2 = aBar.getFoo().doSomething2();
...
}
getFoo() が呼び出される行で、コンパイラは cFoo の一時オブジェクトを生成し、doSomething1() を呼び出せるようにします。コンパイラは、これらの一時オブジェクトに使用されるスタック メモリを再利用しますか? 「some_function_in_the_callstack_hierarchy」の呼び出しで確保されるスタック メモリの数は? 生成された一時ごとにメモリを予約しますか?
私の推測では、コンパイラは cFoo の 1 つのオブジェクトに対してのみメモリを予約し、別の呼び出しに対してメモリを再利用しますが、追加すると
int test3 = aBar.getFoo().doSomething3();
「some_function_in_the_callstack_hierarchy」に必要なスタック サイズは、追加のローカル int 変数のためだけでなく、はるかに大きいことがわかります。
一方、私が次に交換する場合
cFoo getFoo(){ return mFoo; }
参照付き (プライベート メンバーへの参照を返すのは良くないため、テスト目的のみ)
const cFoo& getFoo(){ return mFoo; }
1 つの cFoo のサイズよりもはるかに少ないスタック メモリが必要です。
したがって、コンパイラは、関数内で生成されたすべての一時オブジェクトに対して追加のスタック メモリを予約しているようです。しかし、これは非常に非効率的です。誰かがこれを説明できますか?