2012-05-03 6 views
0

クラスは、新しいインスタンスが作成されるたびに非静的メンバー関数用にメモリを割り当てる必要がありますか?静的メソッドはオーバーヘッドを減らしますか?

私は3-空間ベクトルを表すクラスv3dを書いていた場合、その上に細かくポイントを置くために、私は

v3d::dotProduct(v3d v2)とは対照的に、

static v3d::dotProduct(v3d v1, v3d v2)

を定義することによって、より少ないメモリを使用するのでしょうか?

+4

どちらの場合でも、まだ2つの 'v3d'オブジェクトが存続しています。賢明な_semantics_をまず心配し、次にプロフィールを心配してください。 – ildjarn

+2

また、通常、クラスのメソッドではなく、このようなものを自由な関数にすることが望ましいです。 –

答えて

3

インスタンスごとに静的でも非静的なメンバー関数も格納されません。

v3d_dotProduct(v3d this, v3d v2) 

そしてそれらへの呼び出しがそれに応じて変換されます:非静的メンバ関数の場合、私はそれを理解する方法は、彼らのようなもの(これよりもおそらく少ない読める)に換算されているということです。パフォーマンスを向上させたい場合は、インライン関数を使用することをお勧めします。これは、基本的に関数の内容を呼び出す場所にコピーするためです。私はこれがあなたのメモリ使用量を減少させるとは思わないが、毎秒何度も呼ばれるクラス関数(静的および非静的)に使う価値がある。いずれの場合も

http://www.cplusplus.com/forum/articles/20600/

+0

1:開発者は、メソッド/関数がインライン化されているかどうかをほとんど制御できません。キーワード 'inline'は、コンパイラがメソッドをインライン化するかどうかに影響しません(通常の状況では)。これは、プログラマがこの決定を正しく(そして実際には常に間違って)行うことに悪い知らせを抱いているため、コンパイラ作成者はこの要求を無視してコンパイラで自動的に決定するほうがよいと判断したからです。通常、(必要でない限り)使用することは悪い習慣とみなされます。これは、関数がクラス外で定義されていてもヘッダー内に定義されている場合にのみリンクするために必要です。 –

+1

2:インスタンスごとに静的メソッドもメンバーメソッドも格納されていません(あなたの答えが示唆しているものとは異なります)。 –

+0

@ LokiAstari:それを明確にするために投稿を編集しました。 – orangething

2

メモリ内に関数のインスタンスが1つあります。静的なものとは関係がありません。メンバ関数にはメモリを割り当てません。

多分私は誤解しました。多分あなたは関数が何らかの形でオブジェクト内のスペースを占有することを意味しましたか?いいえ、そうではありません。オブジェクトコードレベルでは、メンバシップは基本的に名前の規約と隠された「this」パラメータです。仮想の場合、通常、すべてのインスタンスに対して同じvtableが存在します。

ただし、例では、すべてのv3dオブジェクトを値渡ししているようです。これは静的なケースでは2つのオブジェクトコピー(各argに1つずつ)を作成しており、静的でない場合にはオブジェクトコピーを1つしか作成していないことを意味します。

argsを参照渡しで渡した場合、ドットプロダクトアルゴリズムが必要とする場合を除き、コピーを作成することを避けることができます(何か数学を行ってから長い時間がかかります)。

+0

しかし、注意してください!議論のコピーを作成することは必ずしも効率的ではない。オブジェクトが小さければ、コピーコンストラクタはほとんど自明であり、引数が多く使われていると、by-copyより渡された方がリファレンスよりも良いかもしれません。これらのケースではいつものように、確実にプロファイルが必要です。 – rodrigo

+0

@rodrigo:コンパイラは最適化を行うこともできます。 const参照を渡すと、コンパイラは元のコピーとして渡すかどうかを決定できます(より効率的であると判断した場合)。したがって、セマンティクスを明確にするためのコードを記述し、コンパイラにマイクロ最適化の決定をさせるのが最善です。 –

1

は、関数のコードは、コードメモリ内の単一のコピーを持っています。静的関数は同じ量のコードメモリを使用しますが、呼び出されたときにスタック上に1つ少ない引数が渡されるため、スタックメモリが少なくなります。非静的クラスメンバ関数には、呼び出されたときにスタックに追加される追加の引数(thisポインタ)があります。 "this"ポインタを使用する必要があるオブジェクト内で何も使用しない場合は、静的関数を宣言する必要があります。

保存するスタックメモリの量はほとんどありません。しかし、関数が1秒間に数百万回呼び出されると、静的関数になります。スタックに追加の引数を渡す必要がないため、速度が向上します。

関連する問題