C ++の明示的なコンストラクターを理解する問題
-
02-10-2019 - |
質問
このスレッドを読んだ後C ++で明示的なキーワードとはどういう意味ですか?
私はこのプログラムを作り上げました
class MyClass
{
public:
explicit MyClass(int a)
{
cout<<"Int was called"<<endl;
val = a;
}
MyClass(char *a)
{
cout<<"Char was called"<<endl;
val = atoi(a);
}
MyClass(const MyClass& copy)
{
cout<<"Copy Const was called"<<endl;
this->val = copy.val;
}
inline const int getval() const
{ return val; }
private:
int val ;
};
メインコード
int main()
{
int x=4;
char y='4';
char *z = &y;
MyClass a(x);
MyClass b(z);
MyClass c(a);
MyClass d('4');
cout<<a.getval()<<endl;
cout<<b.getval()<<endl;
cout<<c.getval()<<endl;
cout<<d.getval()<<endl;
return 0;
}
出力は次のとおりです。
Int was called
Char was called
Copy Const was called
Int was called
4
4
4
52
さて、上記のスレッドによると、コンストラクターがオブジェクトDで呼び出した後、エラーをスローする必要がありますが、そうではありませんでした。
G ++バージョン情報
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
上記のコードで何か間違ったことをしたかどうかはわかりません。助けてください
解決
明示的なコンストラクターは、オブジェクトを初期化するときの「暗黙的な変換」のようなことをすることはできません。
MyClass d = 4;
または、パラメーターで関数を呼び出すとき:
void foo( const MyClass& param);
...
foo( 4);
あなたの場合、明示的なコンストラクターを呼び出す前に、CHARからINTへの変換があります。これは設計どおりです。
他のヒント
実際、構築 d
で行われました int
コンストラクタ。あなたの char
('4'
)暗黙的にanにキャストされました int
. 。これらは両方とも整数数であり、 int
少なくとも同じ幅である char
(その逆の方法では、可能な精度の損失が生じる可能性があるため、明示的なキャストが必要です)。
オブジェクトの出力 d
文字「4」のASCIIコードでした。
explicit
キーワードは、コンストラクターが暗黙的な変換に使用できないことを定義していますが、コードでは、値からオブジェクトの構築を明示的に要求しています。
コードを変更した場合:
MyClass d = 'a';
MyClass x = 5;
その後、変換は暗黙的であり、エラーが発生します。
重要な変換はからではないことに注意してください 'a'
に int
しかし、から int
に MyClass
. 。コンパイラは、からの変換を実行できます 'a'
に int
, 、として MyClass(int)
コンストラクターは、元のコードで明示的に要求されます。
'4'はcharで、intに自由に転換可能です。 52は「4」の文字コードです
「char」( 'd'のように)には、C ++のint値があります。事実、52は「D」の整数ASCII値です。
エラーはありません - 整数値 '4'でINTコンストラクターを呼び出すだけです。これは実際にはU+0034(hex)または番号52です。C/C ++のすべてのchar定数は、内部的にintとして保存されます
どれでも char
リテラルはです int
, 、あなたは言うことができます int i = 'a
;`