C++は関数としての戻り値を参照する
構文:タイプ&関数名(パラメータリスト){関数体}
特に注意:
1.関数としての戻り値を参照する場合は、関数を定義するときに、関数名&
2.関数として参照される戻り値の最大の利点は、メモリに戻り値のコピーが生成されないことです.
Case 1:関数を戻り値で呼び出す(以下の図、ピクチャソース:伯楽オンライン):
グローバル変数tempの値を返すと、C++はメモリに一時変数を作成し、tempの値を一時変数にコピーします.メイン関数mainに戻ると、付与文a=fn 1(5.0)は一時変数の値を変数aにコピーする
Case 2:関数の戻り値で参照を初期化するように関数を呼び出す(以下の図、ピクチャソース:伯楽オンライン)
この場合、関数fn 1()は、値として返され、返されると、まずtempの値を一時変数にコピーする.主関数に戻ると、bがその一時変数からの別名となるように、参照変数bを一時変数で初期化する.一時変数の役割ドメインが短いため(C++標準では、一時変数またはオブジェクトのライフサイクルは、完全な文式が終了すると終了を宣言します.つまり、文float&b=fn 1(5.0).その後)、bは無効な危険に直面するため、以降の値が確定できない値になる可能性が高い.
本当に関数の戻り値で参照を初期化したい場合は、まず変数を作成し、関数の戻り値をこの変数に割り当ててから、その変数で参照を初期化します.
Case 3:参照を返すように関数を呼び出す(以下の図、ピクチャソース:伯楽オンライン)
この場合、関数fn 2()の戻り値はコピーを生成せず、直接変数tempを主関数に返し、すなわち,主関数の付与文の左値は変数tempから直接コピーされる.(すなわち、cは別名ではなく変数tempのコピーにすぎない)これにより、一時変数の生成が回避されます.特に、変数tempがユーザがカスタマイズしたクラスのオブジェクトである場合、クラス内のコピーコンストラクタを呼び出してメモリに一時オブジェクトを作成するプロセスも回避され、プログラムの時間と空間の使用効率が向上します.
Case 4:関数が返す参照を新しい参照の初期化値として関数を呼び出す(以下の図、ピクチャソース:伯楽オンライン)
この場合、関数fn 2()の戻り値はコピーを生成せず、直接変数tempを主関数に返す.主関数では、1つの参照宣言dがその戻り値で初期化され、すなわち、このときdが変数tempの別名となる.tempはグローバル変数であるため、dの有効期間内にtempは常に有効であるため、この方法は安全である.
3.ローカル変数の参照を返すことはできません.上記の例のように、tempがローカル変数である場合、関数が戻った後に破棄され、tempへの参照が「指なし」の参照となり、プログラムは未知の状態になります.
4.関数内でnewで割り当てられたメモリの参照を返すことはできません.ローカル変数のパッシブ破棄の問題はありませんが、返された関数の参照が一時変数としてのみ現れ、実際の変数に値を割り当てていない場合は、これにより、この参照が指す空間(new割り当てがある)が解放されない場合(具体的な変数名がないためdeleteでメモリを手動で解放できない場合)にメモリが漏洩する可能性があるため、このような状況の発生を避けるべきである.
5クラスメンバーの参照を返す場合はconst参照が望ましい.これにより、クラスのメンバーが無意識に破壊されることを回避できます.
6.代入式の左の値として関数で返される参照
実行結果
D.参照によるマルチステートのC++において、参照はポインタ以外のマルチステート効果を発生させる手段である.すなわち、ベースクラスの参照を使用して、派生クラスのインスタンスをバインドできます.
特に注意:
ptrは、派生クラスオブジェクトのベースクラスから継承されたメンバーにのみアクセスできます.ベースクラス(クラスFather)で定義されている虚関数があれば、派生クラス(クラスSon)でこの虚関数を書き換えることでクラスの多様性を実現することができる.
特に注意:
1.関数としての戻り値を参照する場合は、関数を定義するときに、関数名&
2.関数として参照される戻り値の最大の利点は、メモリに戻り値のコピーが生成されないことです.
// :RUNOOB
#include
using namespace std;
float temp;
float fn1(float r){
temp=r*r*3.14;
return temp;
}
float &fn2(float r){ //& temp , temp
temp=r*r*3.14;
return temp;
}
int main(){
float a=fn1(5.0); //case 1:
//float &b=fn1(5.0); //case 2: [Error] invalid initialization of non-const reference of type 'float&' from an rvalue of type 'float'
//( , warning)
float c=fn2(5.0);//case 3:
float &d=fn2(5.0);//case 4:
cout<
Case 1:関数を戻り値で呼び出す(以下の図、ピクチャソース:伯楽オンライン):
グローバル変数tempの値を返すと、C++はメモリに一時変数を作成し、tempの値を一時変数にコピーします.メイン関数mainに戻ると、付与文a=fn 1(5.0)は一時変数の値を変数aにコピーする
Case 2:関数の戻り値で参照を初期化するように関数を呼び出す(以下の図、ピクチャソース:伯楽オンライン)
この場合、関数fn 1()は、値として返され、返されると、まずtempの値を一時変数にコピーする.主関数に戻ると、bがその一時変数からの別名となるように、参照変数bを一時変数で初期化する.一時変数の役割ドメインが短いため(C++標準では、一時変数またはオブジェクトのライフサイクルは、完全な文式が終了すると終了を宣言します.つまり、文float&b=fn 1(5.0).その後)、bは無効な危険に直面するため、以降の値が確定できない値になる可能性が高い.
本当に関数の戻り値で参照を初期化したい場合は、まず変数を作成し、関数の戻り値をこの変数に割り当ててから、その変数で参照を初期化します.
int x=fn1(5.0);
int &b=x;
Case 3:参照を返すように関数を呼び出す(以下の図、ピクチャソース:伯楽オンライン)
この場合、関数fn 2()の戻り値はコピーを生成せず、直接変数tempを主関数に返し、すなわち,主関数の付与文の左値は変数tempから直接コピーされる.(すなわち、cは別名ではなく変数tempのコピーにすぎない)これにより、一時変数の生成が回避されます.特に、変数tempがユーザがカスタマイズしたクラスのオブジェクトである場合、クラス内のコピーコンストラクタを呼び出してメモリに一時オブジェクトを作成するプロセスも回避され、プログラムの時間と空間の使用効率が向上します.
Case 4:関数が返す参照を新しい参照の初期化値として関数を呼び出す(以下の図、ピクチャソース:伯楽オンライン)
この場合、関数fn 2()の戻り値はコピーを生成せず、直接変数tempを主関数に返す.主関数では、1つの参照宣言dがその戻り値で初期化され、すなわち、このときdが変数tempの別名となる.tempはグローバル変数であるため、dの有効期間内にtempは常に有効であるため、この方法は安全である.
3.ローカル変数の参照を返すことはできません.上記の例のように、tempがローカル変数である場合、関数が戻った後に破棄され、tempへの参照が「指なし」の参照となり、プログラムは未知の状態になります.
4.関数内でnewで割り当てられたメモリの参照を返すことはできません.ローカル変数のパッシブ破棄の問題はありませんが、返された関数の参照が一時変数としてのみ現れ、実際の変数に値を割り当てていない場合は、これにより、この参照が指す空間(new割り当てがある)が解放されない場合(具体的な変数名がないためdeleteでメモリを手動で解放できない場合)にメモリが漏洩する可能性があるため、このような状況の発生を避けるべきである.
5クラスメンバーの参照を返す場合はconst参照が望ましい.これにより、クラスのメンバーが無意識に破壊されることを回避できます.
6.代入式の左の値として関数で返される参照
#include
using namespace std;
int value[10];
int error=-1;
int &func(int n){
if(n>=0&&n<=9)
return value[n];// ,
else
return error;
}
int main(){
func(0)=10;
func(4)=12;
cout<
実行結果
10
12
D.参照によるマルチステートのC++において、参照はポインタ以外のマルチステート効果を発生させる手段である.すなわち、ベースクラスの参照を使用して、派生クラスのインスタンスをバインドできます.
class Father;// ( )
class Son:public Father{.....}//Son Father
Son son;//son Son
Father &ptr=son;//
特に注意:
ptrは、派生クラスオブジェクトのベースクラスから継承されたメンバーにのみアクセスできます.ベースクラス(クラスFather)で定義されている虚関数があれば、派生クラス(クラスSon)でこの虚関数を書き換えることでクラスの多様性を実現することができる.