C++explicitキーワード:暗黙変換禁止

7221 ワード

explicitキーワードは、コンストラクション関数によって定義される暗黙的な変換を防止するために使用されます.
このキーワードの意味を理解するには、まずclassタイプのオブジェクトの暗黙的な変換を理解します.単一の実パラメータで呼び出すことができるコンストラクション関数は、パラメータタイプからクラスタイプへの暗黙的な変換を定義します.
例:
class SomeBody{
public:
	SomeBody(const std::string& name =""):
              m_name(name),height(0),weight(10){}
	int CompareTo(const SomeBody& other);
	std::string m_name;
	int height;
	int weight;
}

ここでSomeBodyのコンストラクション関数は,1つの実パラメータのみで初期化を完了することができる.暗黙的に変換できます
SomeBody a;
//................
//          。
std::string nm ="book_1";
//        ,          
int result = a.CompareTo(nm);

このプログラムはstringタイプオブジェクトをSomeBodyのCompareTo関数に実パラメータとして使用します.この関数は本来,実パラメータとしてSomeBodyオブジェクトを必要とする.コンパイラはstring nmを用いて1つを構築し初期化する.
SomeBodyオブジェクトは,新しく生成された一時的なSomeBodyオブジェクトがCompareTo関数に渡され,この関数から離れた後に解析される.
このような行為が正しいかどうかは、ビジネスのニーズにかかっています.aの重さと10の大きさの比をテストしたいだけなら、便利かもしれません.しかし、CompareTo関数で0に初期化するheight属性を除いた場合、これはエラーかもしれません.SomeBodyを構築した後、heightプロパティを0に変更する必要があります.したがって、この暗黙的なタイプの変換を制限します.
この場合、コンストラクション関数をexplicitと宣言することで、暗黙的なタイプ変換を防止することができます.
explicitキーワードは、クラス内部のコンストラクション関数宣言でのみ使用でき、クラス外部の関数定義では使用できません.今、SomeBody類はこうです.
class SomeBody{
public:
    explicit SomeBody(const std::string&name =""):
          m_name(name),height(0),weight(0){}
    int CompareTo(const SomeBody & other);
    std::string m_name;
    int height;
    int weight;
};

この時にビジネスコードをコンパイルするとコンパイルエラーが表示されます.
しかし、コンストラクション関数を使用して、上記のタイプの変換を表示することもできます.
SomeBody a;
................//          。
std::string nm ="book_1";
//        
int result = a.CompareTo(SomeBody(nm));

Googleのc++仕様でexplicitに言及した利点は、時宜に合わないタイプの変換を避けることができ、欠点がないことです.Googleは、すべての単一パラメータのコンストラクション関数を表示しなければならないことを約束しています.コピーコンストラクション関数だけがexplicitと呼ばれることを宣言しないことができます.例えば、他のクラスとしての透明包装器のクラス.
effective c++によると、explicitと宣言された構造関数は、non-explicit兄弟よりも一般的に人気があるという.コンパイラが予期せぬ(往々にして期待されない)タイプ変換を実行することを禁止しているためです.構造関数が暗黙的なタイプ変換に使用されることを許可する良い理由がない限り、explicitとして宣言します.
参照先:https://www.cnblogs.com/winnersun/archive/2011/07/16/2108440.html