Question

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

Was it helpful?

Solution

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.

OTHER TIPS

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top