c++クラスの構造関数の詳細

6299 ワード

c++クラスの構造関数の詳細
一、構造関数は何をしているのか
<span style="font-size:18px;">class Counter
{

public:
         //  Counter     
         //   :        ,     
         Counter()
         {
                m_value = 0;
         }
         
private:
      
         //     
         int m_value;
}</span>

      
クラスオブジェクトが作成されると、コンパイルシステムオブジェクトはメモリ領域を割り当て、コンストラクション関数を自動的に呼び出します->コンストラクション関数によってメンバーの初期化作業を完了します
eg:    Counter c1;
コンパイルシステムは、オブジェクトc 1の各データメンバー(m_value)にメモリ空間を割り当て、コンストラクタCounter()を呼び出してオブジェクトc 1のm_を自動的に初期化するvalue値を0に設定
したがって、
コンストラクション関数の役割:オブジェクトのデータ・メンバーを初期化します.
二、構造関数の種類
<span style="font-size:18px;">class Complex 
{         

private :
        double    m_real;
        double    m_imag;

public:

        //           
        //                  ,                 ,    ,     
        //                  ,                     ,                ,           
        Complex(void)
        {
             m_real = 0.0;
             m_imag = 0.0;
        } 
        
        //          (        )
        //                ,              ,              (  c++       )
        //   :        Complex( int num)       
        //                        
        Complex(double real, double imag)
        {
             m_real = real;
             m_imag = imag;         
         }
        
        //          (         )
        //                     ,                        ,                                
        //                 ,                ,          ,                   ,           “   ” 、“   ”     
        Complex(const Complex & c)
        {
                //    c           
                m_real = c.m_real;
                m_img    = c.m_img;
        }            
    
        //         ,                     
        //   :       double          Complex  
        Complex::Complex(double r)
        {
                m_real = r;
                m_imag = 0.0;
        }

        //        
        //   ,          , =                   ,        ,                
        //        =     ,            =     ,           
        Complex &operator=( const Complex &rhs )
        {
                //                    ,       ,     
                if ( this == &rhs ) 
                {
                        return *this;
                }
                
                //                 
                this->m_real = rhs.m_real;
                this->m_imag = rhs.m_imag;
                
               //             
               //           eg:    a=b=c        b=c
               //      a= ( b=c    ,       c   b  )    
                return *this;
        }

};
</span>

次に、上記で定義したクラスオブジェクトを使用して、各コンストラクション関数の使用方法を説明します.
<span style="font-size:18px;">void main()
{
        //          ,         0.0
        Complex c1,c2;

        //         ,            
        Complex c3(1.0,2.5);
        //           
        Complex c3 = Complex(1.0,2.5);
        
        //     c3          c1
        //      c1       ,             
        //         =         
        c1 = c3;
        
        //              
        //                  , 5.2            ,           ,         c1
        c2 = 5.2;
        
       //         (          ) 
        Complex c5(c2);
        Complex c4 = c2;  //     =        ,                 ,           ,   c2

        
        
}</span>

三、思考とテスト
1.複製構造関数を注意深く観察する
   
     Complex(const Complex & c)
        {
                //    c           
                m_real = c.m_real;
                m_img = c.m_img;
        }    

        
なぜ関数でオブジェクトcのプライベートメンバーに直接アクセスできるのですか?
2.問題に挑戦し、引用と伝達値の違いを理解する
  
Complex test1(const Complex& c)
  {
          return c;
  }
  
  Complex test2(const Complex c)
  {
         return c;
   }
   
   Complex test3()
   {
          static Complex c(1.0,5.0);
          return c;
   }
  
  Complex& test4()
  {
         static Complex c(1.0,5.0);
         return c;
  }
  
  void main()
  {
        Complex a,b;
    
        //                    ,          ?
    
       test1(a);
       test2(a);
     
       b = test3();
       b = test4();
     
       test2(1.2);
       //           ?
       test1(1.2);     //test1( Complex(1.2 ))  ?
  }

 
四、付録(浅いコピーと深いコピー)
 
   
前述したように、カスタムレプリケーションコンストラクション関数がない場合、デフォルトのレプリケーションコンストラクション関数が作成されますが、システムが作成したデフォルトのレプリケーションコンストラクション関数は、コピーされたオブジェクトのデータ・メンバーの値を新規作成されたペアに割り当てる「浅いコピー」のみを実行します.このクラスのデータ・メンバーにポインタ・メンバーがある場合、新しいオブジェクトのポインタが指すアドレスがコピーされたオブジェクトのポインタが指すアドレスと同じになり、deleteポインタをdeleteするとdeleteが2回繰り返されてエラーが発生します.次に例を示します.
 
【浅いコピーと深いコピー】
 
<span style="font-size:18px;">#include <iostream.h>
#include <string.h>
class Person 
{
public :
        
        //     
        Person(char * pN)
        {
              cout << "          !
"; m_pName = new char[strlen(pN) + 1]; // pN if(m_pName != NULL) { // m_pName , pN strcpy(m_pName ,pN); } } // , Person(Person & p) { // m_pName = p.m_pName; } ~Person( ) { delete m_pName; } private : char * m_pName; }; void main( ) { Person man("lujun"); Person woman(man); // man woman // // delete } // , “ ”, , Person(Person & chs); { // new m_pName=new char[strlen(p.m_pName)+ 1]; if(m_pName) { // strcpy(m_pName ,chs.m_pName); } // m_pName chs m_pName }</span>