コンストラクション関数、レプリケーションコンストラクション関数、タイプ変換コンストラクション関数、コンストラクション関数

12464 ワード

コンストラクタ
メンバー関数の一種で、名前はクラス名と同じで、パラメータがあってもよいし、戻り値があってもよい(voidもだめ).1つのクラスには複数の構造関数があります.クラスを定義するときにコンストラクション関数が書かれていない場合、コンパイラはデフォルトの非パラメトリックコンストラクション関数を生成します.このコンストラクション関数は何もしません.コンストラクション関数が定義されている場合、コンパイラはデフォルトの非パラメトリックコンストラクション関数を生成しません.オブジェクトの生成時にコンストラクション関数が自動的に呼び出され、オブジェクトが生成されると、コンストラクション関数を実行することはできません.オブジェクトが占有するストレージ領域はコンストラクション関数ではなく、コンストラクション関数はオブジェクトが占有しているストレージ領域で初期化操作を行います.オブジェクトが生成されると、コンストラクション関数が自動的に呼び出されます.このオブジェクトがどのように生成されても.例:
class Complex{
    private:
        double real,imag;
    public:
        Complex(double r,double i=0);
};
Complex::Complex(double r,double i){
    real=r;imag=i;
}
Complex c1;//error,         
Complex *pc=new Complex;//error,    
Complex c1(2);
Complex c1(2,4),c2(3,5);
Complex *pc=new Complex(3,4);

コンストラクション関数はpublicが好ましく、privateコンストラクション関数はオブジェクトを初期化するために直接使用できません.たとえば、
class CSample{
    private:
        CSample(){}
};
int main(){
    CSample Obj;//err.        private
    return 0;
}

配列内のコンストラクション関数の使用:
class CSample{
    int x;
public:
    CSample(){cout<<"Constructor 1 called"<int n){
        x=n;
        cout<<"Constructor 2 called"<int main(){
    CSample array1[2];//                
    cout<<"step1"<2]={4,5};//                
    cout<<"step2"<2]={3};//       2    ,     1    
    cout<<"step3"<new CSample[2];//                
    delete []array4;
    return 0;
}

      :
Constructor 1 called
Constructor 1 called
step1
Constructor 2 called
Constructor 2 called
step2
Constructor 2 called
Constructor 1 called
step3
Constructor 1 called
Constructor 1 called
class Test{
    public:
        Test(int n){}      //(1)
        Test(int n,int m){}//(2)
        Test(){}           //(3)
};
Test array1[3]={1,Test(1,2)};
//                  ,         (1)(2)(3)   
Test array2[3]={Test(2,3),Test(1,2),1};
//       (2)(2)(1)   
Test *pArray[3]={new Test(4),new Test(1,2)};
//pArray     ,      ,                  。    Test *pArray[3]          ,       ,     Test       。               ,          ,new Test(4)      Test*,           ,                          。          (1)(2)

複製コンストラクタ(コピーコンストラクタ)
X::X(X&)やX::X(const X&)のような同類オブジェクトの参照は、オブジェクトの参照のみであり、オブジェクトではなく、X::X(X)のような有形の複製構造関数は許可されません.レプリケーションコンストラクタが定義されていない場合、コンパイラはデフォルトのレプリケーションコンストラクタを生成し、デフォルトのレプリケーションコンストラクタはレプリケーション機能を完了します.レプリケーションコンストラクタが独自に定義されている場合、デフォルトのレプリケーションコンストラクタは存在しません.コンストラクション関数をコピーして機能する3つのケース:1)同じクラスの別のオブジェクトを1つのオブジェクトで初期化する場合
Complex c2(c1);
Complex c2 = c1;//     ,     ,        
Complex c1,c2;
c2 = c1;//    ,          ,                 

2)ある関数のパラメータがクラスAのオブジェクトである場合、その関数が呼び出されると、クラスAの複製コンストラクタが呼び出されてパラメータが初期化される
class A{
public:
    A(){};
    A(A &a){cout<
};
void Func(A a1){}
int main(){
    A a2;
    Func(a2);//  a1          ,              a2,  a1 a2                  ,                    ,         ,     a1 a2     
    return 0;
}Copy constructor called

3)関数の戻り値がクラスAのオブジェクトである場合,関数が戻ると,Aの複製コンストラクタが呼び出される.
class A{
public:
    int v;
    A(int n){v = n;}
    A(const A &a){
        v = a.v;
        cout<
};
A Func(){
    A b(4);
    return b;
}//                  ,    b,       A      b            
int main(){
    cout<Copy constructor called
4

タイプ変換コンストラクタ
レプリケーション構造関数ではなく、パラメータが1つしかないタイプの自動変換を実現します.コンパイルシステムは、タイプ変換コンストラクション関数を自動的に呼び出し、一時オブジェクト/一時変数を確立します.
class Complex{
public:
    double real,imag;
    Complex(int i){//        
        cout<<"IntConstructor called"<real = i;imag = 0;
    }
    Complex(double r,double i){
        real = r;imag = i;
    }
};
int main(){
    Complex c1(7,8);
    Complex c2 = 12;//     ,            12        ,          
    c1 = 9;//9          Complex  
    cout<real<<","<return 0;
}
  :
IntConstructor called
IntConstructor called
9,0

こうぞうかんすう
名前はクラス名と同じで、前に「~」を付けて、パラメータと戻り値がなく、1つのクラスには最大1つの解析関数しかありません.オブジェクトが消滅すると、構造関数が自動的に呼び出されます.クラスを定義するときに解析関数が書かれていない場合、コンパイラはデフォルトの解析関数を生成します.解析関数が定義されている場合、コンパイラはデフォルトの解析関数を生成しません.構造関数は、ユーザーが申請したメモリの解放などの作業には関与しません.ユーザーが自分でメモリ空間を申請した場合、ユーザーは自分で解放しなければなりません.そうしないと、プログラムは自動的にユーザーが申請したメモリ空間を解放しません.すなわち,プログラムにnewと書かれている場合は対応するdeleteが必要であり,そうでなければプログラム終了時にユーザnewのこの空間を自動的に解析することはない.構造関数と配列:オブジェクト配列のライフサイクルが終了すると、オブジェクト配列の各要素の構造関数が呼び出されます.構造関数と演算子delete:delete演算により、構造関数呼び出しが発生します.
Ctest *pTest;
pTest = new Ctest[3];//      3 
delete []pTest;//      3 

コンストラクション関数とコンストラクション関数の呼び出しタイミング
class Demo{
    int id;
public:
    Demo(int i)
    {
        id = i;
        cout<<"id="<"Constructed"<cout<<"id="<"Destructed"<1);
void Func(){
    static Demo d2(2);
    Demo d3(3);
    cout<<"Func"<int main(){
    Demo d4(4);
    d4 = 6;
    cout<<"main"<5);}
    Func();
    cout<<"main ends"<return 0;
}

出力:id=1 Constructed id=4 Constructed id=6 Constructed id=6 Destructed main id=5 Constructed id=5 Destructed id=2 Constructed id=2 Constructed id=3 Constructed Funcid=3 Destructed main ends id=6 Destructed id=2 Destructed id=1 Destructed id注:1.d 4=6はタイプ変換であり、一時オブジェクトが生成されるため、一時オブジェクトに対して生成されるコンストラクタとコンストラクタの呼び出しがある.2.{Demo d5(5);} オブジェクトに最も近いカッコはオブジェクトの役割ドメインであり、役割ドメインはオブジェクトのライフサイクルを表し、オブジェクトのライフサイクルの終了時にプロファイルされます.3.Func()関数の内部には静的変数d 2と通常変数d 3が定義されており、それらの役割ドメインはこの関数の内部であるが、静的変数はプログラム全体の終了時に解析されるため、Func()の終了時には変数d 3のみが解析される.4.d 4はmain関数内部の局所変数であるため、main関数の終了時にd 4が解析され、d 1はグローバル変数がプログラム全体の終了時に解析され、d 2は静的変数もプログラム全体の終了時に解析され、先に作成された後に解析される.