Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: explicit constructor is implicitly called by derived class

Tags:

c++

Why making a constructor explicit does not prevent it to be implicitly called by derived class?

class A{
public:
    explicit A(){}
};

class B : public A{
public:
    B(){ //Constructor A() is called implicitly

        //...
    }
}

I had a situation in my program when I'd rather have compiler error in that case, it would save me a lot of time to find a bug. For now I changed default constructor of A to accept a dummy "int" argument to achieve that, but shouldn't "explicit" keyword work for this?

g++-4.8 compiles the code above without any errors or warnings.

like image 537
igagis Avatar asked May 29 '26 21:05

igagis


1 Answers

Your assumption is wrong on the explicit keyword.

The explicit keyword isn't meant to prevent the constructor from being called from a derived class but rather to prevent implicit conversions like the one in the sample here: https://stackoverflow.com/a/121163/1938163

I'm summarizing the relevant parts here:

class Foo
{
public:
  // single parameter constructor, can be used as an implicit conversion
  Foo (int foo) : m_foo (foo) 
  {
  }

  int GetFoo () { return m_foo; }

private:
  int m_foo;
};

Since at most one implicit conversion can be done to resolve ambiguities, if you have a function like

void DoBar (Foo foo)
{
  int i = foo.GetFoo();
}

the following is legit:

int main ()
{
  DoBar (42); // Implicit conversion
}

And that's exactly where the explicit keyword comes into play: forbids the case above.

To solve your problem, in order to prevent your class from being used as a base class, just mark the constructor with final if you're using C++11 (http://en.wikipedia.org/wiki/C++11#Explicit_overrides_and_final)

like image 161
Marco A. Avatar answered May 31 '26 11:05

Marco A.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!