名前空間、デフォルトパラメータ、関数のオーバーロード、参照


 
 
 

1.名前空間:

名前空間は新しいスコープを定義し、その中のすべてのコンテンツはその名前空間に制限されます。

この目的:名前の競合や名前の汚染回避するため

名前空間の定義方法

  1. 一般:
namespace N
{
	int a;
	int ADD(int left, int right)
	{
		return left + right;
	}
}
  1. ネストされた定義:
namespace N
{
	int a;
	int ADD(int left, int right)
	{
		return left + right;
	}
	namespace N1
	{
		int a;
		int ADD(int left, int right)
		{
			return left + right;
		}
	}
}
  1. 同じファイルに、同じ名前の名前空間が複数あり、コンパイラーは最終的に1つの名前空間にマージされます
namespace N
{
	int a;
	int ADD(int left, int right)
	{
		return left + right;
	}
}
namespace N
{
	int c;
	int d;
}

注: 3番目の方法は、同じ名前空間であり、異なる場所に書き込まれ、最終的にマージされます。同じ変数または関数名は使用できません(パラメーターの型はまったく同じです)。そうしないと、再定義が発生します

名前空間の使用:

  1. 以下::を使用したN::变量/函数
    N::c;
  2. using N(命名空间名):: 变量/函数
    頻繁に使用される名前空間の場合など特定の変数または関数の使用は、そのまま使用できます。このようにして、変数は現在のファイルで「グローバル変数」になり、プロジェクト全体で関数を直接呼び出すことができます。
    といった:
using N::ADD;// ②
using N::a;

int main()
{
	N::c;//①
	return 0;
}
  1. using namespace N(命名空间);
    名前空間変数または関数を使用すると、かなり頻繁に使用できます。名前空間のすべてのメンバースコープは、ファイルのグローバルな役割と見なされます。

 
 
 

2.デフォルトのパラメーター:

デフォルトのパラメータは、関数を宣言または定義するときにパラメータのデフォルト値指定することです関数が呼び出されたときに、実パラメータが指定されていない場合はデフォルト値が使用され、それ以外の場合は指定された実パラメータが使用されます。

デフォルトのパラメータタイプ:

  1. 完全なデフォルトパラメータ:すべての関数パラメータにはデフォルト値があります。
int ADD(int first = 1, int second = 2, int third = 3)
{
	return first + second + third;
}
  1. 準デフォルトパラメータ:一部の関数パラメータのみにデフォルト値があります。
int ADD(int first, int second, int third = 3)
{
	return first + second + third;
}

注意:

  1. セミデフォルトパラメータは、右から左に指定する必要があります
  2. デフォルトのパラメータを関数の宣言と定義に同時に含めることはできません
  3. デフォルト値は定数またはグローバル変数でなければなりません

関数の宣言と定義だけで指定できます。繰り返し表示される場合は、デフォルトパラメータの再定義が表示されます。

通常、デフォルトのパラメーターのデフォルト値を関数宣言で指定することをお勧めします。

3.関数のオーバーロード:

関数のオーバーロード:C ++では、同じ名前の同じような関数を持ついくつかの関数が同じスコープで宣言さます同じ名前のこれらの関数の仮パラメーターリスト(パラメータータイプ、パラメーターの数、パラメーターの順序)が異なります。

パラメータリストのさまざまな症状:

  1. パラメーターの数が異なります。パラメーターの数が異なる同じ名前の次の2つの関数は、関数のオーバーロードを構成します。
int ADD(int right, int left)
{
	return right + left;
}

int ADD()
{
	return 10;
}
  1. 異なるパラメーターの種類:次の同じ名前の2つの関数には異なるパラメーターの種類があり、関数のオーバーロードを構成します。
int ADD(int right, int left)
{
	return right + left;
}

double ADD(double right,double left)
{
	return right + left;
}
  1. パラメータタイプ順序が異なります。同じ名前の次の2つの関数では、パラメータタイプの順序が異なります。これは、関数のオーバーロードを構成します。
double ADD(int right, double left)
{
	return right + left;
}

double ADD(double right, int left)
{
	return right + left;
}

そのようなコード:

int ADD(int right, int left)
{
	return right + left;
}

double ADD(double right, double left)
{
	return right + left;
}

int main()
{
	ADD(1, 2.2);
	return 0;
}

このコードにはどのようなエラーが表示されますか?

関数呼び出しの過程で、仮パラメーターはインスタンス化されますが、完全に一致する型はありません暗黙的な型変換行われますint->double 或者double->int入力しますが、上記の呼び出しでは、両方の変換を実行できることがわかります。コンパイラーはどちらを選択するかわかりません。エラーになります。

VS2017でのエラー報告:
ここに画像の説明を挿入
このエラーは、あいまいさ|あいまいさと呼ばれます。

関数のオーバーロード呼び出しの原則:コンパイル段階で呼び出す関数を決定する

  1. コンパイル段階では、コンパイラーはタイプを推定し、呼び出す推定結果に従ってタイプに一致する関数を見つけます。
  2. タイプ完全に一致する関数がある場合は、直接呼び出します。
  3. 型が完全に一致する関数がない場合、暗黙的な型変換実行されます。
  4. 暗黙の型変換の後に対応する関数(あいまいさなしがある場合、それが呼び出されます。
  5. 曖昧さがないか、不明確な場合は、エラーが報告されます。

したがって、ADD(1、2.2)を実行すると、あいまいさ、複数の変換、およびコンパイラエラーが発生します。

関数の戻り値の型は異なり、関数のオーバーロードを構成しません。

int ADD(int right, int left)
{
	return right + left;
}

double ADD(int right, int left)
{
	return right + left;
}

これは関数のオーバーロードを構成しません。

C言語が関数のオーバーロードをサポートしないのはなぜですか?C ++は関数のオーバーロードをサポートしていますか?

VS環境を見てみましょう。

int ADD(int right, int left);

int main()
{
	ADD(1, 2);
	return 0;
}

関数定義がない場合、エラーが報告されます。
C ++では、
ここに画像の説明を挿入
エラーは次のとおりです。C言語では、エラーは次のとおりです
ここに画像の説明を挿入
上記のコードは同じですが、コンパイラーはコンパイル時に下部で異なる名前を使用します。

C言語:_
関数名にC ++を追加するだけ:関数名をと解釈します?ADD@@YAHHH@Z
C ++の場合、戻り値の型はdouble、パラメーターの型はdouble、関数名は何ですか?
ここに画像の説明を挿入
ここに画像の説明を挿入

 
 
 
Linux環境での状況を見てみましょう:
C ++:
ここに画像の説明を挿入
C言語:
ここに画像の説明を挿入
C言語では、関数の変更が比較的簡単であることがわかります。C ++は関数の装飾に固有であり、Linuxでは、関数名の長さと関数のパラメータータイプの最初の文字が含まれます。

したがって、C言語は関数を比較的簡単に変更するため、関数のオーバーロードをサポートしていません。同じ名前の関数がある場合、再定義が行われます。C ++では、関数パラメーターの型も変更されます。同じ名前の関数のパラメーターリストが異なると、基礎となる説明も異なります。

 
 
 

C言語とC ++関数の違いは何ですか?

  1. 戻り値のタイプ:

C言語の場合:関数には戻り値の型がなく、システムはデフォルトでint型を返します。
C ++:戻り値の型を取得する必要があります。それ以外の場合、プログラムはエラーを報告します。

  1. 関数パラメーター:

C言語の場合:関数にはパラメーターがありませんが、呼び出し時にパラメーターが渡され、コンパイラーはそれをコンパイルできます。
C ++では、関数にはパラメーターがなく、呼び出し時にパラメーターが渡され、コンパイラーはそれをコンパイルできません。

  1. C ++関数パラメーターはデフォルト値を持つことができます:デフォルトのパラメーター
  2. 関数の命名規則は異なります。C++は関数のオーバーロードをサポートしていますが、C言語はサポートしていません

C ++コンパイラーは、C言語コンパイラーよりも厳密な構文検出を備えています。
 
 
 
 

4.見積もり:

参照は、現在の既存の変数のエイリアスですコンパイラは、参照用のスペースを開きませんが、参照された変数とメモリスペースを共有します。
ここに画像の説明を挿入
参照変数と参照変数は同じメモリ空間を共有します。
データが変更されると、参照される変数も変更されます。

参照型は変数型と一致している必要があります。

引用されたメモ:

  1. 定義時に初期化する必要がありますつまり、参照する変数を指定します。
  2. 変数は複数の参照を持つことができます。つまり、エンティティには複数のエイリアスがあります。
  3. エンティティを参照した後、他のエンティティを参照することはできません。

定数を参照するときは、constも追加する必要があり、エンティティを参照で変更することはできません。

int main()
{
	double d = 12.56;
	const int& rd = d;
	return 0;
}

上記のコードは正常に引用できます。しかし問題があります:
ここに画像の説明を挿入

どうしてこれなの?
参照変数は、参照エンティティのタイプと一致します。doubleとintの間には暗黙的な型変換があり、doubleはintに変換されます。
rdはdを参照し、コンパイラーは遷移として一時スペースを作成します。rdがこの一時スペースを参照するようにします。
ただし、このスペースのアドレスは通常の状況では不明であり、変更できません。したがって、この空間は恒常性(一定の特性)を持っています。
rdは定数を引用することと同じです。constを追加する必要があります。

 
 
参照アプリケーションシナリオ:

  1. コードは簡潔にしてください。
  2. 関数パラメータを作成します。
  3. 関数の戻り値を実行します。

関数の戻り値に注意してください。

  1. 返されたオブジェクトがシステムに返されている場合、参照によって返すことはできません。それ以外の場合は、不正な領域が返されます。
  2. 戻されたオブジェクトがシステムに戻されない場合は、参照による戻りを使用できます。

関数の値渡しと参照渡しの比較:参照渡しは、値渡しよりもはるかに高速です。これは、参照による仮パラメーターのインスタンス化のプロセスがなく、仮パラメーターがエンティティーの単なるエイリアスであり、パラメーターのスタックによるオーバーヘッドが減少するためです。はるかに高速。

ポインターによる関数の受け渡しと参照による受け渡しの比較:2つの効率は似ています。

void Swap(int& right, int& left)
{
	int tmp = right;
	right = left;
	left = tmp;
}

void Swap(int *right, int *left)
{
	int tmp = *right;
	*right = *left;
	*left = tmp;
}

int main()
{
	int a = 10;
	int b = 20;
	Swap(a, b);

	Swap(&a, &b);
	return 0;
}

逆アセンブル:
ここに画像の説明を挿入
2つのコードによって実行される操作が同じであることがわかりました。参照はポインタの方法で操作されます。

これは、下部にある参照操作とポインタによって実装されます。

参照とポインターの違い:

  1. 概念的な観点から:
    Reference:は変数のエイリアスであり、コンパイラーはそのためのスペースを開きません。参照とエンティティはスペースを共有します。
    ポインター:コンパイラーはそのためのスペースを割り振り、ポインターはアドレスを指します。
  2. 最下位レベルから:参照とポインターの間に違いはありません-参照はポインターです
  3. 特徴的な観点から:

1.参照を初期化する必要があり、ポインタは必要ありません
2.エンティティが参照されると、他のエンティティを参照できなくなります。ポインタは、タイプと一致する任意のアドレスを指すことができ
ます。3. NULL参照はありませんが、NULLポインタがあります
。4. sizeofでは、参照の結果は参照タイプのサイズであり、ポインタは32ビットプラットフォームでは常に4バイトです
。5.からの参照エンティティに1を加え、1を加えると、ポインタはそのタイプのサイズに1を加えます。6。
マルチレベルポインタはありますが、マルチレベル参照はありません
。7 エンティティにアクセスする場合、ポインタを逆参照する必要があり、参照を直接使用できます
。8。参照比率ポインタは比較的安全です

おすすめ

転載: blog.csdn.net/w903414/article/details/108714494