Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need an example showing that default constructor is not inherited

I know that default constructor is not inherited, as stated in n3337.

And there is an example there:

struct B2 {
  B2(int = 13, int = 42);
};

struct D2 : B2 {
  using B2::B2;
};

With quite good explanation:

The candidate set of inherited constructors in D2 for B2 is

...
—B2(int = 13, int = 42)
—B2(int = 13)
—B2()

And most important:

The set of constructors present in D2 is
—D2(), implicitly-declared default constructor, not inherited

For me this example does not show the difference, in a sense that even if this very constructor was inherited - its behavior was not different from the implicitly-declared default constructor.

I need an example showing the difference in the way that can be easily understand for, let say, an audience familiar with C++03 but wanting to learn C++11.


[UPDATE]
All answers (including my own) are of kind "if default c-tor was inherited then the example would compile/not compile".

I'd prefer answers where the outcome (observable behavior) is different than it would be otherwise.

like image 624
PiotrNycz Avatar asked Apr 23 '14 15:04

PiotrNycz


3 Answers

One possible difference: multiple-constructor-inheritance from classes with default constructors. For example:

struct A { A(int=0); };
struct B { B(double=3.14); };
struct C : A, B {
  using A::A;
  using B::B;
};

C c;

If default constructors were inherited, C would inherit one from both A and B, resulting in ambiguity.

I can't think of a use case for multiple-constructor-inheritance, so this may not be the perfect example you're looking for, but it's something.

like image 104
Casey Avatar answered Nov 03 '22 15:11

Casey


Consider:

struct foo
{
    foo() {}
    foo(int) {}
};

struct bar : foo
{
    using foo::foo;
};

int main()
{
    bar b;
}

This compiles: Since bar has no user-declared constructors, a default constructor will be declared implicitly.

struct foo
{
    foo() {}
    foo(int) {}
};

struct bar : foo
{
    using foo::foo;
    bar(double) {}
};

int main()
{
    bar b;
}

This does not compile. The default constructor is not inherited, and it is not declared implicitly, since there is the bar(double) constructor.

like image 37
dyp Avatar answered Nov 03 '22 16:11

dyp


Here is the example, that can be produced from the following feature of inherited constructors:

12.9 Inheriting constructors
[...]
4) A constructor so declared has the same access as the corresponding constructor in X.

So my proposal is to have protected default constructor in base:

class Base {
protected:
    Base(int) {}
    Base() = default;
};

If this constructor was derived, then derived class cannot be instantiated because derived constructor would have protected access. If not derived - then default implicitly declared constructor has public access:

struct Derived : Base {
    using Base::Base;
};

int main() {
    Derived d1{};  // not inherited, default constructor is public
    Derived d2{1}; // not compiling since this c-tor is inherited, thus protected
}
like image 29
PiotrNycz Avatar answered Nov 03 '22 17:11

PiotrNycz