パラメータのデフォルトと関数のオーバーロードの説明

風雨を乗り越えて意志を研ぎ澄まし、苦楽を分かち合い輝きを生み出した3年間

目次

1. パラメータデフォルトの概念

2. パラメータのデフォルトの使用法

3. デフォルトパラメータの分類

3.1. すべてのデフォルトパラメータ

3.2. 準デフォルトパラメータ

4. 関数のオーバーロードの概念

5. 関数オーバーロードの使用法

6. 関数オーバーロードの原理


1. パラメータデフォルトの概念

       一般に、関数を呼び出すときの実パラメータの数は仮パラメータの数と同じである必要がありますが、関数をより便利に使用するために、C++ ではデフォルト パラメータを使用して関数を定義することもできます
       デフォルトパラメータとは、関数を定義する際に仮パラメータにデフォルト値(デフォルト値)を指定することを指しますこのような関数が呼び出されるとき、デフォルト パラメータには、実際のパラメータ値を指定することも、パラメータ値を指定しないこともできます。実パラメータが指定されている場合は、その実パラメータが仮パラメータに渡されて呼び出されます。実パラメータが指定されていない場合は、デフォルト値が呼び出されます。        デフォルト パラメータを使用した関数呼び出し: デフォルトの実パラメータは定数式である必要はなく、任意の式にすることができ、関数呼び出しによって指定することもできます。デフォルトの引数が式の場合、その式は関数が呼び出されるたびに再評価されます。しかし、その表現には意味があるはずです。
       

 


2. パラメータのデフォルトの使用法

例として次の写真を見てみましょう。

3. デフォルトパラメータの分類

3.1. すべてのデフォルトパラメータ

完全なデフォルトとは、すべてのパラメータにデフォルト値が与えられることを意味します

3.2. 準デフォルトパラメータ

セミデフォルトとは、パラメータの半分をデフォルトにするのではなく、パラメータの一部をデフォルトにすることです。

準デフォルト ルール:次の例のように、デフォルトは右から左に設定する必要があります。

  デフォルトパラメータの呼び出しメソッド:

 デフォルトの 2 つのパラメータの呼び出しメソッド:

4. 関数のオーバーロードの概念

関数フォーカスとは、同じスコープ内に、同じ名前を持つ複数の関数が存在するが、仮パラメータ リストが異なり (パラメータの種類、パラメータの数、パラメータの順序が異なる)、戻り値が無関係であることを意味します。これを私たちは呼びます。オーバーロードされた関数の一種。オーバーロードされた関数はパラメータ リストによって区別され、他の関数とは何の関係もありません。一言で言えば、「1 つのインターフェイス、複数の実装」です。

例: 加算演算を実装する場合、加算関数は整数または浮動小数点にすることができ、関数のオーバーロードを使用して実現できます。

5. 関数オーバーロードの使用法

加算演算を実装する場合、加算関数は整数または浮動小数点にすることができ、関数のオーバーロードを使用して実現できます。

例えば:

int Add(int a, int b)
{
	return a + b;
}
float Add(int a,float b)
{
	return a + b;
}
float Add(float a, int b)
{
	return a + b;
}
float Add(float a, float b)
{
	return a + b;
}

 5.1 パラメータの種類が異なる

int add(int left, int right)
{
	cout << "int add(int left, int right)" << endl;

	return left + right;
}

double add(double left, double right)
{
	cout << "double add(double left, double right)" << endl;

	return left + right;
}

5.2 パラメータの数が異なる

void f()
{
	cout << "f()" << endl;
}

void f(int a)
{
	cout << "f(int a)" << endl;
}

5.3 パラメータの順序が異なる

void f(int a, char b)
{
	cout << "f(int a,char b)" << endl;
}

void f(char b, int a)
{
	cout << "f(char b, int a)" << endl;
}

注: 戻り値は異なり、呼び出し時に区別できないため、オーバーロードを構成することはできません。

6. 関数オーバーロードの原理

(前書き:この部分はあまり深く理解していないので詳しくは書きませんが、一緒に読みましょう~~)

C言語では関数のオーバーロードがサポートされていないのに、C++では関数のオーバーロードがサポートされているのはなぜか疑問に思ったことはありますか? C++ はそれをどのようにサポートしていますか?

VS コンパイラを使用して関数のオーバーロードの原理を実証するのは不便であり、Linux オペレーティング システムが必要です

Linux システムで C 言語プロジェクトを作成します。

func.h の time 関数の宣言、func.cの time 関数の定義、およびtest.cの main 関数

 このプロジェクトをコンパイルします。

 この時点で、次のエラー メッセージが表示されます。

f()関数 をコメントアウトしないとコンパイルは成功しません。次の図は、パラメータなしでf()関数をコメントアウトした後の実行結果です。

 ここで、C 言語が関数のオーバーロードをサポートできないことが確認されます。

上記のコードを C++ でコンパイルして実行します。

 ここで確認されるのは、C++ がオーバーロードをサポートしているということです。

次に、C 言語では関数のオーバーロードがサポートされていないのに、C++ では関数のオーバーロードがサポートされるのはなぜかということです。C++はどのようにサポートされていますか? ここがポイントです(黒板をノックしてください!!)

コンパイルとリンクのプロセスを確認してみましょう。

 このうち、C 言語は関数のオーバーロードをサポートしておらず、C++ は関数のオーバーロードをサポートしていることが、ここにリンクする理由です。

関数呼び出しがアセンブリ コードでどのように実装されるかを観察してみましょう。

 C 言語は関数のオーバーロードをサポートしていません。これは、コンパイル時にオーバーロードされた 2 つの関数の関数名が同じであり、Func.o シンボル テーブルに曖昧さと競合があり、リンク時に曖昧さと競合が発生するためです。直接関数名は識別と検索に使用され、オーバーロードされた関数は同じ関数名を持ちます。

C++ は、C++ オブジェクト ファイルのシンボル テーブル内の関数を識別および検索するために関数名が直接使用されないため、関数のオーバーロードをサポートしています。C++ では関数名の変更ルールを参照しますが、変更ルールはコンパイラによって異なります。変更 原則として、パラメータが異なる限り、func.o のシンボルに曖昧さや矛盾は生じません。リンクするときに、test:o の main 関数で 2 つのオーバーロードされた関数を呼び出してアドレスを見つけることも明らかです。

 この記事はここで終わります~~

 

おすすめ

転載: blog.csdn.net/m0_73648729/article/details/129472368