メンバー関数のパラメーター名の変更について質問があります。
私は関数を持っていてfoo(type iA)
、に変更しfoo(type iB)
ます。ビンコンプだと思いますが、よくわかりません。
理由を説明するのを手伝ってくれませんか?どうもありがとう!
メンバー関数のパラメーター名の変更について質問があります。
私は関数を持っていてfoo(type iA)
、に変更しfoo(type iB)
ます。ビンコンプだと思いますが、よくわかりません。
理由を説明するのを手伝ってくれませんか?どうもありがとう!
引数の名前は、引数を区別するためのものです。関数宣言と関数定義で異なる名前を使用できます。
だからこれは大丈夫です:
void foo(int bar); // Declare function
...
// Define function
void foo(int bibibibibi)
{
...
}
上記の宣言と定義は、同じ関数に対するものです。C++ は、引数名に基づいて関数をオーバーライドまたはオーバーロードせず、引数の型のみに基づいています。
コンパイラは、デバッグ情報を除いて、引数 (または他の変数) の名前を保存しません。実際に生成されたコードには、変数名に関する情報はありません。
もちろんオブジェクトの型を変えないのでバイナリ互換になります。したがって、サイズは同じままです。変数名は人間専用です。
実際には、次のように名前を付けずに関数を宣言できます。
int funct(void*, int, Object)
定義すると、好きなものを使用できます
int funct(void* ptr, int something , Object object){return 42;};
それは結構です。クラスのメンバーにも有効です。
バイナリ互換性または非互換性の (主な) 理由は、渡されたオブジェクトのサイズです。したがって、実際のバイナリ データを操作する場合、アセンブラー レベルではオフセットは変化しません。型を変更した場合、引数はメモリ内の別の場所に存在し、それらのオフセットを再計算する必要があります。重要なのは、エイリアスや名前ではなくアドレスです。
編集:
完全を期すために。@Lightness が指摘したように、定義で名前をスキップすることもできるため、私が示したまさにその例は次のようになりますint funct(void*, int, Object){return 42;};
。
@Jamesのコメントについても。2 つのオブジェクトが同じサイズの場合、ぼやけます。もちろん、あるタイプから別のタイプへのそのような乱暴な変換は意味がありません。ただし、前の例を考慮すると、オペランドを使用しない場合は、おそらく機能します... アセンブラー レベルで。サイズが異なると、スタックが破損します。
しかし、この問題についてどのようにコメントするかを考えたとき、あなたは について尋ねていると自分に言い聞かせましたc++
。それでは、この観点から見てみましょう。署名が変更されない場合、関数はバイナリ互換性があると言えます。また、オペランドの名前は、定義の一部ではありません。関数シグネチャは、名前マングリングとオーバーロードの基礎であり、最終的なバイナリ オブジェクトのシンボル名です。