2

such is the code,and with the error:"illegal member initialization: 'a' is not a base or member",what is the meaning of the error info,and why??

class A{
public:
int a;
};
class B:public A{

public:
B();
};

B::B():a(10){    // put  "a(10)" into the constructor body is right

}
iammilind
  • 68,093
  • 33
  • 169
  • 336
hu wang
  • 411
  • 3
  • 12
  • possible duplicate of [Initialize parent's protected members with initialization list (C++)](http://stackoverflow.com/questions/2290733/initialize-parents-protected-members-with-initialization-list-c) – iammilind Aug 07 '12 at 02:42
  • before ask this question,I have searched,but find none!! – hu wang Aug 07 '12 at 02:52

4 Answers4

8

By the time the constructor of the derived class is invoked, the base class must already be constructed. So it's already too late. To see why it must be this way, consider:

class Base
{
    public:
    int i;
    Base(int q) : i(q) { ; }
};

class Middle : public Base
{
    public:
    Middle() : Base(2) { printf("i=%d\n", i); }
};

class Derived : public Middle
{
    public:
    Derived() : i(3) { ; }
}

Now, think about it. The Middle constructor has to run before the Derived constructor. And the Middle constructor ensures that i is 2. So how can the Derived constructor later re-construct it with a different value?

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
2

See this answer for a more complete explanation of what's going on here. Basically, you cannot initialise A::a in the initialiser of B, because it is ill-formed according to the standard.

Community
  • 1
  • 1
Anthony
  • 12,177
  • 9
  • 69
  • 105
1

One more important piece of information - remember that if a class does not initialise a member object via the constructor initialization list, then the default constructor for that member will be invoked before that first statement in the base class constructor is executed. When you use the initialiser, what you are actually doing is specifying a constructor to be used INSTEAD of the default constructor.

Clearly when you are constructing a derived class, the parent class member has thus already been constructed, so you cannot reconstruct the base member again, which is what you are trying to do in this example by including it in the derived class initialisation list.

As an aside, if you all you want is to have the derived class be able to set the value of A::a to a specific value, then use the following code instead:

B::B()
{
    a = 10;
}
Ozraptor
  • 564
  • 4
  • 11
0

Because the base class may want to initialize things its own way. The proper method is to call on of the base constructors in the initializer list and let the base ctor initialize itself.

Antimony
  • 37,781
  • 10
  • 100
  • 107