1

I do have a struct

struct MyStruct {
    MyStruct( XML cfg ) { ... }
    int m_1, m_2, ... ;
}

And a class

class MyBaseClass {
    public:
    MyBaseClass() {}     
    MyStruct m_struct;
}

class MyClass : public MyBaseClass {
    public:
    MyClass( XML cfg ) { m_struct = MyStruct( cfg ); }        
}

Now the compiler is complaining that MyStruct does not have an empty constructor

error: no matching function for call to ‘MyStruct::MyStruct()’
 MyClass( XML cfg ) { m_struct = MyStruct( cfg ); }

I dont think teh inheritance plays a role ehre, but I kept it for completeness as it may be the case. I never explicitly call an empty constructor for MyStruct. Does the class MyClass do that because m_struct is its member?
If that is teh case, is there a way to not have it initialize the member or is this only possible with pointers as members?

I am aware I can fix this by just adding an empty constructor to my structure or by changing the constructor to

MyClass( XML cfg ) : m_struct = MyStruct( cfg ) {}

but I am curious to know what exactly is going on here.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
chrise
  • 4,039
  • 3
  • 39
  • 74
  • `struct` and `class` are the same. They don't form useful categories here. – juanchopanza Apr 05 '17 at 05:54
  • I use a struct because it only contains a couple of public members. the class itself contains a lot more than my example here, I just try to be minimalsitic in my example – chrise Apr 05 '17 at 05:57
  • Inheritance indeed plays no role here. You can completely remove MyClass, instantiate MyBaseClass, and have exactly the same problem. – WhozCraig Apr 05 '17 at 05:57
  • @chrise Yes, I think I misread the question. But if you want to be minimalistic, you can use `struct` for everything. It involves less typing (you don't have to say `public` everywhere. – juanchopanza Apr 05 '17 at 05:59
  • You can find a very good answer here: http://stackoverflow.com/questions/926752/why-should-i-prefer-to-use-member-initialization-list – mcrlc Apr 05 '17 at 06:04

2 Answers2

1

If you omit the member initializer, the compiler will insert one using no arguments. Hence the error.

This also means that in your first extract where you initialize the member inside the constructor body, the member gets initialized twice, if the compiler permits. Don't write code like this.

user207421
  • 305,947
  • 44
  • 307
  • 483
1

does a class construct members on class construction?

Of course yes. The issue occurs at the constructor of MyBaseClass, which doesn't initialize the member m_struct explicitly, then it will be default initialized, but MyStruct doesn't have a default constructor.

This is true not only for the data member, also for the base class object. For the constructor of MyClass, it doesn't explicitly specify the constructor of the base class, then the default constructor of MyBaseClass will be invoked, then cause the error as the above explained.

You can add a default constructor for MyStruct, or use member intializer list at the constructor of MyBaseClass, to call MyStruct::MyStruct( XML cfg ) explicitly to intialize the member m_struct. e.g.

MyBaseClass() : m_struct(some_thing) {}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • Thanks. I wasnt aware of that. I happened to use smart pointers as members that the instance itself, so in my few weeks of tinkering with c++ I actually never stumbled across that issue – chrise Apr 05 '17 at 06:12
  • @chrise Smart pointers can be default constructed; so everything is fine. – songyuanyao Apr 05 '17 at 06:18