C++プログラミングにおける構造関数の詳細

3470 ワード

C++解析関数
オブジェクトを作成すると、コンストラクション関数が自動的に初期化され、オブジェクトを破棄すると、コンストラクション関数と呼ばれるクリーンアップ作業(オブジェクトを作成するときに消費されるさまざまなリソースを回収するなど)のために関数が自動的に呼び出されます.
構造関数(Destructor)も特殊なメンバー関数で、値を返さず、ユーザー呼び出しを必要とせず、オブジェクトを破棄するときに自動的に実行されます.コンストラクション関数とは異なり,コンストラクション関数の名前はクラス名の前に"~"記号を付ける.
注意:構造関数にはパラメータがなく、リロードできないため、クラスには構造関数が1つしかありません.ユーザーが定義していない場合、コンパイラは自動的に生成されます.
構造関数の例:

#include 
using namespace std;
class Student{
private:
  char *name;
  int age;
  float score;
public:
  //    
  Student(char *, int, float);
  //    
  ~Student();
  //      
  void say();
};
Student::Student(char *name1, int age1, float score1):name(name1), age(age1), score(score1){}
Student::~Student(){
  cout< 
 

実行結果:

       15,    90.5
       16,    95
       16,    80.5
main         
    
    
    

構造関数はmain関数の実行が終了する前に実行され,呼び出し順序と構造関数は正反対であり,記憶を容易にするためにスタックとして理解でき,先に入ってから出る.構造関数の実行順序がなぜ逆なのか.構造関数は、オブジェクトが破棄される前に実行されます.構造関数がいつ呼び出されるかを知るには、オブジェクトがいつ破棄されるかを知る必要があります.
オブジェクトは、クラスというデータ型によって定義された変数と考えられ、その多くの特性は、役割ドメイン、ライフサイクルなどの一般的な変数と同じである.これにより,オブジェクトのこのような変数の破棄タイミングは通常の変数と同じであると推定できる.
まとめると、1)1つの関数にオブジェクト(autoローカル変数)が定義されている場合、この関数の実行が終了するとオブジェクトが破棄され、オブジェクトが破棄される前に自動的に構造関数が実行されます.
2)staticローカルオブジェクトは、関数呼び出し終了時に破棄されないため、構造関数も呼び出さず、プログラム終了時(main関数終了やexit関数呼び出しなど)にのみstaticローカルオブジェクトの構造関数が呼び出されます.
3)グローバルオブジェクトが定義されている場合でも、プログラムの終了時にのみグローバルオブジェクトの構造関数が呼び出されます.
4)new演算子でオブジェクトが動的に作成された場合、delete演算子でオブジェクトを解放すると、オブジェクトの構造関数が呼び出されます.
注意:構造関数の役割は、オブジェクトを削除することではなく、オブジェクトが使用するメモリを取り消す前にクリーンアップ作業を完了し、このメモリを新しいオブジェクトに割り当てることができます.
C++コンストラクション関数とコンストラクション関数を呼び出す順序コンストラクション関数とコンストラクション関数を使用する場合は、それらの呼び出し時間と呼び出し順序に特に注意する必要があります.一般に、構造関数を呼び出す順序は、構造関数を呼び出す順序とは正反対です.最初に呼び出された構造関数は、対応する(同じオブジェクトの)構造関数が最後に呼び出され、最後に呼び出された構造関数は、対応する構造関数が最初に呼び出されます.例9.5に示すように、stud 2の構造関数を先に実行し、stu 1の構造関数を実行する.
先構造の後析構造、後構造の先析構造は、スタックに相当し、先進的に後出する.
しかし、いずれの場合もこの原則に従って処理されるわけではない.オブジェクトは、異なる役割ドメインで定義でき、異なるストレージカテゴリを持つことができます.これらは、コンストラクション関数とコンストラクション関数を呼び出すタイミングに影響します.
次に、コンストラクション関数とコンストラクション関数を呼び出すタイミングをまとめます.1)グローバル範囲で定義されたオブジェクト(すなわち、すべての関数以外で定義されたオブジェクト)で、ファイル内のすべての関数(main関数を含む)が実行される前に呼び出されます.ただし、1つのプログラムに複数のファイルがあり、異なるファイルにグローバルオブジェクトが定義されている場合、これらのオブジェクトのコンストラクション関数の実行順序は不確定です.main関数の実行が完了したりexit関数が呼び出されたりすると(プログラムが終了します)、構造関数が呼び出されます.
2)ローカル自動オブジェクト(関数でオブジェクトを定義するなど)が定義されている場合、オブジェクトの作成時にコンストラクション関数が呼び出されます.関数が複数回呼び出されると、オブジェクトが作成されるたびにコンストラクション関数が呼び出されます.関数呼び出しが終了し、オブジェクトが解放されると、まず構造関数が呼び出されます.
3)関数に静的(static)ローカルオブジェクトを定義する場合、プログラムがこの関数を最初に呼び出してオブジェクトを確立するときにのみコンストラクション関数を1回呼び出し、呼び出し終了時にオブジェクトは解放されないため、コンストラクション関数も呼び出さず、main関数が終了するかexit関数終了プログラムを呼び出すときにのみ、コンストラクション関数を呼び出す.
たとえば、1つの関数で2つのオブジェクトを定義します.

void fn(){
  Student stud1; //        
  static Student stud2; //        
}

fn関数を呼び出す場合は、stud 1のコンストラクション関数を呼び出し、stud 2のコンストラクション関数を呼び出す.fn呼び出しが終了すると、stud 1は解放される(自動ローカルオブジェクトであるため)ため、stud 1のコンストラクション関数を呼び出す.一方、stud 2は静的ローカルオブジェクトであり、fn呼び出しの終了時に解放されないため、stud 2の構造関数は呼び出されない.プログラムがstud 2の解放を終了するまで、stud 2の構造関数が呼び出されません.stud 2は後でコンストラクション関数を呼び出すが,そのコンストラクション関数を先に呼び出すわけではないことがわかる.なぜなら、2つのオブジェクトのストレージカテゴリが異なり、ライフサイクルが異なるためです.