c++中關於explicit的一些總結

首先看下以下代碼

#include <iostream>
using namespace std;

class A
{
  public:
    A(int v): value(v) { cout << "構造" << endl;}
    int value;
};

void f(A a)
{
  cout << "f()" << endl;
}

int main()
{
  f(1);
  return 0;
}
以上代碼可以編譯通過
之所以能夠調用函數f成功是因爲在調用函數之前,編譯器將整數1隱式地轉化爲對象A

如果我們在該構造函數之前加上 explicit 關鍵字,那麼,再次調用就失敗了,從 explicit字面意思就可以知道,explicit是

明確的,清楚的;直言的;詳述的;不隱瞞的意思,也就是阻止隱式轉換,所以,以下代碼編譯出錯

#include <iostream>
using namespace std;

class A
{
  public:
  explicit A(int v): value(v) { cout << "構造" << endl;}
    int value;
};

void f(A a)
{
  cout << "f()" << endl;
}

int main()
{
  f(1);
  return 0;
}

explicit的本質就是使得該函數顯示調用,不能隱式轉換,如果將以上的代碼中的f(1)改成f(A(1)),則編譯通過


考慮下面兩個語句

A a;

A b1(a);

A b2 = a;

顯然熟悉C++的同學都知道2,3兩句其實都是調用了A的拷貝構造函數,下面這段代碼可以檢驗一下

#include <iostream>
using namespace std;

class A
{
  public:
   A(){}
   A(const A& a){cout << "拷貝構造" << endl;}
};

int main()
{
  A a;
  A b1(a);
  A b2 = a;
  return 0;
}

但是2,3兩句還是有細微的差別的,即 A b1(a);是顯示調用拷貝構造函數,而 A b2 = a;是隱式調用拷貝構造函數,所以,我們如果在拷貝構造函數前面加入explicit,就阻止了拷貝構造函數的隱式調用,進而使得 A b2 = a;編譯出錯

#include <iostream>
using namespace std;

class A
{
  public:
   A(){}
   explicit A(const A& a){cout << "拷貝構造" << endl;}
};

int main()
{
  A a;
  A b1(a);
  A b2 = a;
  return 0;
}
最後:
如果你能瞭解下面這段代碼爲什麼出錯,你就可以算得上懂得explicit的意義了

#include <iostream>
using namespace std;

class A
{
  public:
   A(){}
   explicit A(const A& a){cout << "拷貝構造" << endl;}
};

void f(A a)
{
}

int main()
{
  A a;
  f(a);
  return 0;
}

最後的組後,再偷偷地告訴你一個好消息:explicit只能用在構造函數哦^^
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章