Here is the code:
class B;
class C;
class D;
class A{
public:
virtual ~A(){}
friend void gg(D* d);
void ga(B *b,C* c,D* d);
};
class B:protected A{
public:
void gb(B *b,C* c,D* d);
};
class C:public B{};
class D:public C{};
void A::ga(B *b,C*c,D*d){
A *a1=b; // error: 'A' is an inaccessible base of 'B'
A *a2=c; // error: 'A' is an inaccessible base of 'C'
A *a3=d; // error: 'A' is an inaccessible base of 'D'
}
void B::gb(B *b,C*c,D*d){
A *a1=b; // no problem here
A *a2=c; //why do classes derived from B can sucessfully convert to A here?
A *a3=d; //why do classes derived from B can sucessfully convert to A here?
}
void gg(D* d){
A* a=d;
}
int main(){
B b;
C c;
D d;
A a;
gg(&d); // error: 'A' is an inaccessible base of 'D'
a.ga(&b,&c,&d);
b.gb(&b,&c,&d);
A a1(d); //error here;Does it mean the implicit conversion in the user code is also user code?
A a4=d; //same as above
return 0;
}
Here's the C++ primer said about accessibility of Derived-to-Base Conversion:
• User code may use the derived-to-base conversion only if D inherits publicly from B. User code may not use the conversion if D inherits from B using either protected or private.
• Member functions and friends of D can use the conversion to B regardless of how D inherits from B. The derived-to-base conversion to a direct base class is always accessible to members and friends of a derived class.
• Member functions and friends of classes derived from D may use the derived-to- base conversion if D inherits from B using either public or protected. Such code may not use the conversion if D inherits privately from B.
But it didn't talk about the conversion happen in B from C/D to A or conversion happen in A from B/C/D to A.I thought the first conversion would fail and second will success.But the result(see the comments in the code) surprises me.
Class A is the Base class of class B/C/D,so I thought Derive-to- Base conversion happened in A (in void A::ga(B*,C*,D*)) will success but the compiler complainted.From rule 2 of the reference from C++ primer I know conversion from B to A in void B::gb(B*,C*,D*) will sucess,but why conversion from C/D to A in void B::gb(B*,C*,D*) also success too? Why ?