見出し画像

c++ | explicitコンストラクタについてのメモ

Qtを勉強していて、コードにexplicitと先頭につけられたものを見て、何だこれはと思ったので調べました。

コンストラクタにこのexplicit修飾子をつけると、暗黙的に型変換されることを防止できる。

コンストラクタはexplicitを付けないとコンパイラが暗黙的に型変換する仕様となっているので、それだと意図しないものが型変換されてコンパイルが通ってしまいまずい。ちゃんと明示的に表現しないとコンパイルが通らないようにしたい(エラーにしたい)ときにexplicitを付ける。


すたっくおーばーふろーより抜粋↓

struct A {
A(int) { }
};
struct B {
B(A) { }
};
int main() {
B b(1);
}

この例だとメイン関数の中のB b(1);を実行すると、コンストラクタBのインスタンスbに引数1を渡したb(1);が実行されることになる。

B b(1);
→struct B { B(A){} };が呼ばれる。

→b(1);の部分はBのインスタンスなので、b(1)はB(A)だと解釈される。

→つまりここからstruct A { A(int){} };が呼ばれ(1)はintの1なのでA(1)と明示していないけど、暗黙的に(1) = A(int) = A(1)と解釈される。

→以上からメイン関数の中のB b(1);のコンパイルが通ったことになる。

ここで、explicitをstruct A, Bのどちらに付けたらいいのかという問題になるけど、(1) = A(int)と暗黙的な変換をしていることから(struct Bが呼ばれさらにstruct Aが呼ばれる間接的変換)、struct Aの方にexplicitを付ければよいことになる。

→explicit A(int);とすることで、このA(int)がb(1) = b(A(1))のように暗黙的な変換をすることを防止され、b(1)だとエラーが出るようになるので、b(A(1))と明示しないとコンパイルが通らないようになる。

もしstruct Bにexplicitをつけて、struct Aにexplicitを付けてない場合、メイン関数の中のB b(1);はstruct Bからみるともともと明示されている状態なので、コンパイルは通ってしまうので、この例ではstruct Bの方にexplicitを付けても意味がないことになる。







この記事が気に入ったらサポートをしてみませんか?