Categories: MSDN / DotNet / Java / Scripts / Linux / PHP Ask - La ask - La Answer

Initialization list and inheritance

Hi there!

I am puzzled by what I think must be a subtlety of C++ when list-initialiazing member variables in derived classes...

Here's what I mean...

class A { // warning l337proggy alert! ;-)
public:
A(int v=9812); // default value provided since this base constructor
// is called by derived classes' constructors
~A();
int getValue();
public:
int value; // it's public, but I don't care!
};
A::A(int v) : value(v) {
cout<<"A() , "<<value<<endl;
}
A::~A() {
cout<<"~A()"<<endl;
}
int A::getValue() {
return value;
}
class B : public A {
public:
B(int v=1);
~B();
};
B::B(int v) {
cout<<"B() , "<<value<<endl; // value is still 9812
}
B::~B() {
cout<<"~B()"<<endl;
}
class C : public B {
public:
C(int v);
~C();
int setValue(int v);
};
C::C(int v) {
cout<<"C() , "<<value<<endl; // 9812 because of A::A()
value=v;
cout<<" "<<value<<endl;
}
C::~C() {
cout<<"~C()"<<endl;
}
int C::setValue(int v) {
value=v;
}
int main(void) {
B *b = new B(5);
C *c = new C(10);
cout<<b->getValue()<<endl;
cout<<c->getValue()<<endl;
c->setValue(32);
cout<<c->getValue()<<endl;
delete b;
delete c;
return 0;
}

Well, so far, so good... But, something weird's happening when I change C::C() and use an initialization list instead of an assignement in the body...

C::C(int v) : value(v) {
cout<<"C() , "<<value<<endl;
}

GCC (version 3.3) is really not happy with that!:

proggy.cpp:41: error: class `C' does not have any field named `value'

Ok, _now_ I'm confused! I thought derived classes had access to all non-private data of their base class?

I guess there is something absolutely trivial that I'm missing here... Yeah, hard to believe I'm been using C++ for years, isn'it? (albeit on a very on and off basis...)

Is there someone to help?

Yon
--
Linux/Mac OS X
GCC 3.2[CODE]Hi there!

I am puzzled by what I think must be a subtlety of C++ when list-initialiazing member variables in derived classes...

Here's what I mean...

class A { // warning l337proggy alert! ;-)
public:
A(int v=9812); // default value provided since this base constructor
// is called by derived classes' constructors
~A();
int getValue();
public:
int value; // it's public, but I don't care!
};
A::A(int v) : value(v) {
cout<<"A() , "<<value<<endl;
}
A::~A() {
cout<<"~A()"<<endl;
}
int A::getValue() {
return value;
}
class B : public A {
public:
B(int v=1);
~B();
};
B::B(int v) {
cout<<"B() , "<<value<<endl; // value is still 9812
}
B::~B() {
cout<<"~B()"<<endl;
}
class C : public B {
public:
C(int v);
~C();
int setValue(int v);
};
C::C(int v) {
cout<<"C() , "<<value<<endl; // 9812 because of A::A()
value=v;
cout<<" "<<value<<endl;
}
C::~C() {
cout<<"~C()"<<endl;
}
int C::setValue(int v) {
value=v;
}
int main(void) {
B *b = new B(5);
C *c = new C(10);
cout<<b->getValue()<<endl;
cout<<c->getValue()<<endl;
c->setValue(32);
cout<<c->getValue()<<endl;
delete b;
delete c;
return 0;
}

Well, so far, so good... But, something weird's happening when I change C::C() and use an initialization list instead of an assignement in the body...

C::C(int v) : value(v) {
cout<<"C() , "<<value<<endl;
}

GCC (version 3.3) is really not happy with that!:

proggy.cpp:41: error: class `C' does not have any field named `value'

Ok, _now_ I'm confused! I thought derived classes had access to all non-private data of their base class?

I guess there is something absolutely trivial that I'm missing here... Yeah, hard to believe I'm been using C++ for years, isn'it? (albeit on a very on and off basis...)

Is there someone to help?

Yon
--
Linux/Mac OS X
GCC 3.2
[4856 byte] By [Yanosa] at [2007-11-11 7:33:11]
# 1 Re: Initialization list and inheritance
It's not so trivial, and I'm afraid that your compiler's error message is quite misleading. Class C does't have a member called v, but it has this member inside its B subobject, which has it inside its A subobject. So technically speaking, this member is accessible to C but your initialization list does more than just access it: it tries to preempt the constructor of C's base classes, which is of course illegal. What you should do instead is initialize the *base* subobject, not a member thereof:

C::C(int v) : B(v) {
cout<<"C() , "<<value<<endl;
}
Danny at 2007-11-11 21:02:08 >
# 2 Re: Initialization list and inheritance
Works now! Thanks a lot!

Yan.
Yanosa at 2007-11-11 21:03:08 >