开发者

Problem understanding explicit constructor in C++

After reading this thread What does the explicit keyword mean in C++?

I made up this program

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 ;
};

main code

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<&l开发者_运维知识库t;b.getval()<<endl;
  cout<<c.getval()<<endl;
  cout<<d.getval()<<endl;

  return 0;
}

The output was:

Int was called
Char was called
Copy Const was called
Int was called
4
4
4
52

Now, as per thread above, it should throw error after the constructor call on object d but it didn't.

g++ version info

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) 

I am not sure if i have done something wrong in the above code. Please help


Explicit constructor will not allow you to do something like "implicit conversion", e.g. when initializing an object:

MyClass d = 4;

or when calling a function with parameters:

void foo( const MyClass& param);

... 

foo( 4);

In your case, there is a conversion from char to int before calling the explicit constructor, which is as designed.


Actually, constructing d was done with the int constructor. Your char ('4') was implicitly casted to an int. This is legal in C/C++ since these are both integer numbers, with int being at least as wide as char (the other way round needs an explicit cast, as possible precision loss can result).

The output for object d was the ASCII code for the character "4".


The explicit keyword defines that the constructor is not available for implicit conversions, but in your code you are explicitly requesting the construction of the objects from the values.

If you change the code to:

MyClass d = 'a';
MyClass x = 5;

Then the conversion is implicit and you will get an error.

Note that the conversion that is important is not from 'a' to int but from int to MyClass. The compiler is allowed to perform the conversion from 'a' to int, as the MyClass(int) constructor is explicitly requested in your original code.


'4' is a char, which is freely convertible to int. 52 is the character code for '4'


A "char" (as in 'd') has an int value in C++. Infact, 52 is the integer ASCII value of 'd'.


There is no error - it just invokes your int constructor with the integer value '4', which is actually U+0034 (Hex) or the number 52. All char constants in C/C++ are stored as int internally


Any char literal is an int, you can say int i = 'a;`

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜