C++構造函數初始化列表與構造函數中的賦值的區別


C++類中成員變量的初始化有兩種方式:構造函數初始化列表和構造函數體內賦值。

一、內部數據類型(char,int……指針等)

  class Animal

  {

  public:

    Animal(int weight,int height): //A初始化列表

      m_weight(weight),

      m_height(height)

    {

    }

    Animal(int weight,int height) //B函數體內初始化

    {

      m_weight = weight;

      m_height = height;

    }

  private:

    int m_weight;

    int m_height;

  }

  對於這些內部類型來說,基本上是沒有區別的,效率上也不存在多大差異。

  當然A和B方式不能共存的。

二、無默認構造函數的繼承關系中

  class Animal

  {

  public: 

    Animal(int weight,int height): //沒有提供無參的構造函數

      m_weight(weight), 

      m_height(height)

    {

    }

  private:

    int m_weight;
    int m_height;
  };
 
  class Dog: public Animal
  {
  public:
    Dog(int weight,int height,int type) //error 構造函數 父類Animal無合適構造函數
    {
    }
  private:
    int m_type;
  }
  上面的子類和父類編譯會出錯:
  因為子類Dog初始化之前要進行父類Animal的初始化,但是根據Dog的構造函數,沒有給父類傳遞參數,使用了父類Animal的無參數構造函數。而父類Animal提供了有參數的構造函數,
  這樣編譯器就不會給父類Animal提供一個默認的無參數的構造函數了,所以編譯時報錯,說找不到合適的默認構造函數可用。要么提供一個無參數的構造函數,
  要么在子類的Dog的初始化列表中給父類Animal傳遞初始化參數,如下:
  class Dog: public Animal
  {
  public:
    Dog(int weight,int height,int type) : Animal(weight,height) //必須使用初始化列表增加對父類的初始化
    {
      this->m_type = type;
    }
  private:
    int m_type;
  }
三、類中const數據成員、引用數據成員,必須在初始化列表中初始化,不能使用賦值的方式初始化
  class Dog: public Animal
  {
  public:
    Dog(int weight,int height,int type) : Animal(weight,height),m_type (type),LEGS(4) //必須在初始化列表中初始化
    {
      this->m_type = type;//error
      //LEGS = 4; //error
    }
  private:
    int& m_type;
    const int LEGS;
  }
四、包含有自定義數據類型(類)對象的成員初始化 
  class Food
  {
  public:
    Food(int type = 10)
    {
      m_type = type;
    }
    Food(Food &other) //拷貝構造函數
    {
      m_type = other.m_type;
    }
    Food & operator =(Food &other) //重載賦值=函數
    {
      m_type = other.m_type;
      return *this;
    }
  private:
    int m_type;
  };
   (1)、構造函數賦值方式 初始化成員對象m_food
  class Dog: public Animal
  {
  public:
    Dog(Food &food)
      //:m_food(food)
    {
      m_food = food; //初始化 成員對象
    }
  private:
    Food m_food;
  };
  //使用
  Food fd;
  Dog dog(fd);
  結果:
  先執行了對象類型構造函數Food(int type = 10)
  然后再執行對象類型構造函數Food & operator =(Food &other)
  想象是為什么?
   (2)、構造函數初始化列表方式
  class Dog: public Animal
  {
  public:
    Dog(Food &food) : m_food(food) //初始化 成員對象
    {
      //m_food = food;
    }
  private:
    Food m_food;
  };
  //使用
  Food fd;
  Dog dog(fd);
  結果:執行Food(Food &other)拷貝構造函數完成初始化
 

  不同的初始化方式得到不同的結果:明顯構造函數初始化列表的方式得到更高的效率。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM