C++学習要約の2:構造関数と構造関数


コンストラクション関数とコンストラクション関数はクラスの2つの特殊なメンバー関数です.
1.コンストラクタ
コンストラクション関数(constructor)は、クラス名と同名のクラスの特殊なメンバー関数です.クラスのオブジェクトを定義すると、コンストラクション関数がシステムによって自動的に呼び出され、オブジェクトの初期化が実現されます.
コンストラクション関数には戻り値が指定できないため、voidを含む戻り値のタイプを指定することはできません.
コンストラクション関数の定義は、他のメンバー関数の定義と同様にクラス内またはクラス外に配置できます.
コンストラクション関数の定義形式は次のとおりです.
クラス名(シェイプの説明)
{関数体}
コンストラクション関数は、問題の必要に応じて、パラメータなし関数として定義することもできます.
注:プログラムではコンストラクション関数を直接呼び出すことはできません.コンストラクション関数はオブジェクトの作成時にシステムによって直接呼び出されるため、コンストラクション関数ではクラスメンバー変数の初期化が一般的に完了します.
2.コンストラクション関数のリロード
1つのクラスに同じ名前のメンバー関数が2つ以上存在する場合、クラスと呼ばれるメンバー関数のリロード.
クラスのメンバー関数のリロードでは、比較的一般的な形式はコンストラクション関数のリロードであり、クラスにリロードコンストラクション関数が現れた場合、C++言語はコンストラクション関数のパラメータの個数とタイプに応じて適切なコンストラクション関数を選択してオブジェクトの構造を完了します.
3.デフォルトコンストラクタとデフォルトパラメータのコンストラクタ
クラスに定義されたコンストラクション関数が表示されない場合、コンパイルシステムはクラスにデフォルトのコンストラクション関数を提供します.このデフォルトのコンストラクション関数は、パラメータなし関数であり、関数体が空であり、オブジェクトの作成のみを担当し、初期化作業を行わない(つまり、対応するデータ・メンバーに初期値を付与しない).したがって、クラスのオブジェクトが作成されると、特定の初期状態が保証されません.
良好なプログラミング習慣は、クラスに適切な初期化作業を完了する構造関数を提供することであるべきである.
しかし、クラスがコンストラクション関数を定義している限り(必ずしもパラメトリックコンストラクション関数ではない)、コンパイルシステムはデフォルトのコンストラクション関数を提供しません.
コンストラクション関数にデフォルトパラメータがある場合は、デフォルトパラメータを持つコンストラクション関数と呼ばれ、デフォルトパラメータを持つコンストラクション関数を使用する場合は、二義性を防止します.
     
 
4.コピーコンストラクタ
コピーコンストラクション関数は特殊なコンストラクション関数です.コピーコンストラクション関数の一般的なフォーマットを次のように定義します.
クラス名::クラス名(constクラス名&形式パラメータ)
{関数体}
コピーコンストラクション関数の関数名はクラス名と同じ名前です.この関数にも戻り値はありません.
コピーコンストラクション関数の機能は、同じオブジェクトの値を新しいオブジェクトにコピーすることによって、新しいオブジェクトの初期化を完了します.すなわち、1つのオブジェクトで別のオブジェクトを構築します.
クラスの定義にコピーコンストラクタが定義されていない場合、コンパイルシステムは、クラスの共有メンバーとして、上記の形式のデフォルトのコピーコンストラクタを自動的に生成します.
5.構造関数
コンストラクション関数に対応するのはコンストラクション関数です.オブジェクトが定義されると、コンストラクション関数が自動的に呼び出され、オブジェクトが使用され、オブジェクトが消える前にクラスのコンストラクション関数が自動的に呼び出され、システムリソースが解放されます.
構造関数もクラスの特殊なメンバー関数であり、その関数名はクラス名の前に「~」を付ける.戻り値もパラメータもありません.1つのクラスに1つの構造関数しか持たないため、構造関数を再ロードすることはできません.
構造関数の定義方法は、次のとおりです.
~クラス名()
{関数体}
プログラマがクラスを定義するときにクラスに構造関数を指定しない場合、デフォルトの構造関数が自動的に作成されます.この形式は次のとおりです.
~クラス名()
  { }
オブジェクトが析出される順序は、作成時の順序とは正反対であり、すなわち、最後に構築されたオブジェクトが最初に析出される.
オブジェクトがnew演算子によって動的に作成されている場合、delete演算子を使用して解放されると、deleteは構造関数を自動的に呼び出します.
6.あるクラスのオブジェクトを別のクラスのデータメンバーとする
クラス内のデータ・メンバーがクラスのオブジェクトである場合、このメンバーは新しいクラスのサブオブジェクトまたはオブジェクト・メンバーと呼ばれ、新しいクラスの定義フォーマットは次のように表すことができます.calss X
{
   1 1;
   2 2;
   3 3;
    ……………
   n n;
    ….………… //
};
,X , 1、 2、……、 n 。 :
class A {};
class B
{
   A a;
};
B ( B ) , A 。 A , 。
 
 
新しいクラスのコンストラクション関数の一般的な定義形式は、次のとおりです.
新しいクラス(パラメータテーブル0):メンバー1(パラメータテーブル1)、メンバー2(パラメータテーブル2)、...、メンバーn(パラメータテーブルn)
  {    ……..     }
ここで、メンバー1、メンバー2、…、メンバーnは、新しいクラスのオブジェクトメンバーである.パラメータテーブル1は、メンバー1を初期化するために必要なパラメータを提供する、パラメータテーブル2は、メンバー2を初期化するために必要なパラメータを提供する、これに類する、これらのパラメータテーブルのパラメータは、いずれもパラメータテーブル0から来ている.また、新しいクラスの非オブジェクトメンバーを初期化するために必要なパラメータも、パラメータテーブル0によって提供されます.
7.常態および常態メンバー
(1)ノーマルオブジェクト
通常オブジェクトとは、次の形式で定義されたオブジェクト定数です.
constクラス名オブジェクト名;
フォーマットから、通常オブジェクトの定義は一般オブジェクトの定義と比較してクラス名の前にconstキーワードを付けなければならないことがわかります.
通常のオブジェクトには、次のような特徴があります.
l通常オブジェクトは定義時に初期化されなければならず、プログラムで更新できない.
l通常オブジェクトを介してクラス内の通常メンバー関数のみを呼び出すことができ、クラス内の他のメンバー関数を呼び出すことはできません.
(2)常オブジェクトメンバー
常オブジェクトメンバーは、常メンバー関数と常データメンバーに分けられます.
1)常メンバー関数
クラスでは、キーワードconstを使用して説明されたメンバー関数が常メンバー関数となり、常メンバー関数の説明フォーマットは次のとおりです.
タイプ関数名(パラメータテーブル)const;
クラス内の通常メンバー関数は、通常のメンバー関数と比較して、次のような特徴があります.
l常メンバー関数はクラスの読取り専用関数であり、このメンバー関数はデータメンバーの値を読み取ることができるが、データメンバーの値を更新することはできず、クラスにconst修飾のない他のメンバー関数を呼び出すこともできない.
l常メンバー関数定義のconstキーワードは関数タイプの一部であるため、その実装部分にもconstキーワードを付ける.
l常メンバー関数定義のconstキーワードは、リロード関数の区別に関与することができる.
例:#include <iostream.h>
 
class Test_const{
       private:
              int m;
       public:
              Test_const(int arg1) //
              {
                     m=arg1;
              }
              void setvalue(int newvalue);
              void showvalue();
              void showvalue() const; //
};
 
void Test_const::setvalue(int newvalue)
{
       m=newvalue;
}
void Test_const::showvalue()
{
       cout<<"m="<<m<<endl;
}
void Test_const::showvalue() const // const
{
       cout<<"const example m="<<m<<endl;
}
 
void main()
{
       Test_const c1(100); // c1
       const Test_const c2(100); // c2
       c1.setvalue(200);
       c1.showvalue(); // void showvalue();
       c2.showvalue();    // void showvalue() const;
// c2.setvalue(200); c2
}

  2)
クラスで定義されたデータ・メンバーは、一般変数に加えてconst定数としても使用できます.このデータ・メンバーを常データ・メンバーと呼びます.
コンストラクション関数は、オブジェクトのデータ・メンバーを初期化できますが、データ・メンバーが定数メンバーまたは参照メンバーの場合、コンストラクション関数で直接付与文で付与することはできません.コンストラクション関数に付属する初期化テーブルを使用して初期化する必要があります.すなわち、コンストラクション関数のカッコの後ろに「:」と初期化テーブルを付けます.フォーマットは次のとおりです.
クラス名::クラス名(パラメータテーブル):常データメンバー名1(値1)、常データメンバー名2(値2)、…{
 //
}

複数のデータ・メンバーがある場合、初期化テーブルの初期化項目は複数あり、カンマで区切る必要があることがわかります.
8.クラスの役割ドメイン
クラス役割ドメインはクラスドメインとも呼ばれ、クラス定義でカッコで囲まれた範囲を指します.
異なるクラスのメンバー関数には同じ名前を付けることができます.したがって、メンバー関数が属するクラスを示すには、役割ドメイン演算子「::」を使用します.
クラスのメンバー関数では、クラスのデータ・メンバーを直接参照できます.ただし、メンバー関数で同じ名前のローカル変数が定義されている場合は、混乱しないように、役割ドメイン演算子「::」で指定する必要があります.例:#include <iostream.h>
class Region{
private:
       int x;
       int y;
public:
       Region(int x,int y)
       {
              Region::x=x;
              Region::y=y;
       }
       void print()
       {
              cout<<"x="<<x<<",y="<<y<<endl;
       }
};
void main()
{
       Region region(5,10);
       Region *p;
       p=&region;
       region.print();
       p->print();
}

 
クラス外からクラスのメンバーにアクセスする場合は、オブジェクト名とドットメンバー選択子'."または、オブジェクトへのポインタと矢印メンバー選択子'->'です.前の例の文regionのように.print()と文p->print()等価です.