c++類大四個默認函數-構造函數 析構函數 拷貝構造函數 賦值構造函數


  每個類只有一個析構函數和一個賦值函數,但可以有多個構造函數(包含一個拷貝構造函數,其它的稱為普通構造函數)。對於任意一個類A,如果不編寫上述函數,C++編譯器將自動為A 產生四個缺省的函數,例如:

  A(void);//缺省的無參數構造函數

  A(const A&a);//缺省的拷貝構造函數

  ~A();//缺省的析構函數

  A&operator=(const A &a);//缺省的賦值構造函數

1)、“缺省的拷貝構造函數”和“缺省的賦值函數”均采用“位拷貝”而非“值拷貝”的方式來實現,倘若類中含有指針變量,這兩個函數注定將出錯。

2)、當類還沒有生成的時候,調用大是拷貝構造函數,當類已經生成的時候,調用的是賦值構造函數,如下所示:

  A a;

  A b;

  b = a;//此時類a和b都已經生成了,所以調用的是賦值構造函數

  A c;

  A d=c;//此時類d還沒有生成,所以調用的是拷貝構造函數

3)、所有的函數調用傳參數,調用的都是拷貝構造函數。如果函數參數用的是引用類型,則不會發生參數的拷貝,也就不會調用任何函數了。

如下:

  void print_a(const A a);//調用拷貝構造函數

  void print_b(const A &a);//為引用,不會調用任何函數

4)、拷貝構造函數和賦值構造函數對實現。

  A::A(const A&a)

  {

  }

  拷貝構造函數沒有返回,為一個全新的類。

 

  A &A::operator=(const A&a)

  {

    return *this;

  }

  賦值構造函數返回自身,即*this,為在原先的類上大操作。

 

explicit:explicit構造函數是用來防止隱式轉換的。

  C++提供了關鍵字explicit,聲明為explicit的構造函數不能在隱式轉換中使用

  C++中, 一個參數的構造函數(或者除了第一個參數外其余參數都有默認值的多參構造函數), 承擔了兩個角色。 1、是個構造器 ,2 是個默認且隱含的類型轉換操作符
所以, 有時候在我們寫下如 AAA = XXX, 這樣的代碼, 且恰好XXX的類型正好是AAA單參數構造器的參數類型, 這時候編譯器就自動調用這個構造器, 創建一個AAA的對象。
這樣看起來好象很酷, 很方便。 但在某些情況下(見下面權威的例子), 卻違背了我們(程序員)的本意。 這時候就要在這個構造器前面加上explicit修飾, 指定這個構造器只能被明確的調用/使用, 不能作為類型轉換操作符被隱含的使用。
  
class Test1
{
public:
    Test1(int n)
    {
        num=n;
    }//普通構造函數
private:
    int num;
};
class Test2
{
public:
    explicit Test2(int n)
    {
        num=n;
    }//explicit(顯式)構造函數
private:
    int num;
};
int main()
{
    Test1 t1=12;//隱式調用其構造函數,成功
    Test2 t2=12;//編譯錯誤,不能隱式調用其構造函數
    Test2 t2(12);//顯式調用成功
    return 0;
}
  Test1的構造函數帶一個int型的參數,Test1 t1 = 12會隱式轉換成調用Test1的這個構造函數。而Test2的構造函數被聲明為explicit(顯式),這表示不能通過隱式轉換來調用這個構造函數,因此Test2 t2 = 12會出現編譯錯誤。
      普通構造函數能夠被隱式調用。而explicit構造函數只能被顯式調用。


免責聲明!

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



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