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

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

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

  class Animal指針

  {對象

  public:繼承

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

      m_weight(weight),編譯

      m_height(height)class

    {效率

    }變量

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

    {

      m_weight = weight;

      m_height = height;

    }

  private:

    int m_weight;

    int m_height;

  }

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

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

2、無默認構造函數的繼承關係中

  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;
  }
3、類中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;
  }
4、包含有自定義數據類型(類)對象的成員初始化 
  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)拷貝構造函數完成初始化
 

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

相關文章
相關標籤/搜索