Reputation: 349
In my program I have an abstract class from which several classes inherit. Each child class introduces a member variable to store data. I noticed that when attempting to initialize the child class, whether using aggregate initialization or initializer list, I get errors, shown below.
struct FooBase {};
struct Foo : FooBase { int value; };
int main()
{
Foo f = {8}; // "initializer for aggregate with no elements requires explicit braces"
Foo f{8}; // same error as above
}
I figured this is because Foo inherits the constructors from FooBase, but I have a couple questions about the behavior.
Foo
take precedence? As I understand, the options would be setting the data after initialization (or making a setter method) or explicitly defining a constructor for Foo
. However, specifically in the context of the last question, what happens with move and copy constructors? (Is there good practice for ensuring classes are well behaved under inheritance?)
Upvotes: 5
Views: 2025
Reputation: 6154
In your example you need to provide additional empty braces to initialize base class:
Foo f = {{}, 8};
Foo f{{}, 8};
Generally speaking though, not every class can be aggregate-initialized. The class is considered to be an aggregate if it has (see the source):
Also, there is no such thing as an "aggregate constructor" and a default constructor is not related to aggregate initialization in any way.
Constructors of base classes are not inherited unless you use using Base::Base
to do so. Copy and move constructors are also not inherited. They are automatically generated by the compiler for each class unless they are explicitly defined or implicitly deleted.
Upvotes: 6
Reputation: 1146
The default constructor is a constructor which takes no arguments and value initializes all the members of a class; a constructor which takes an int
and uses it to initialize value
would have to be a user-defined constructor.
Constructors are not passed onto their children. If you add the using declaration using FooBase::FooBase
in the definition of Foo
then all of the constructors of FooBase
will become visible in Foo (although in this example this would have no effect as FooBase
only contains the constructors that are provided by default).
Upvotes: 2