Everyone needs a friend!
Classes are no different: when they need to share big or small secrets (private or protected) then they need to know they have a friend. Simply addin a line to your A class stating that C is a friend will allow access to the otherwise inaccessible members and functions:
friend class C;
Immediately after the last }
of the foo()
function will allow C access.
This link at cplusplus.com will help with more detail about friend classes, although, in most cases a rethink of the inheritance hierarchy may be in order if you find yourself having to grant friend status too often.
here is a modified version of your source with friends:
#include <iostream>
class A {
protected:
void foo() {
std::cout << "Hello world!\n";
}
friend class C;
};
class B : public A {
};
class C : public A {
public:
void bar(B* other) {
foo(); //OK
other->foo(); //no error if A and C are friends
}
};
int main() {
B* b = new B();
C* c = new C();
c->bar(b);
return 0;
}
Let me know if you need more info:)
Addendum:
The error occurs because you have a layer of indirection and whilst B or C can access a protected method from their immediate ancestor A, they cannot access it via an instance of the other class, because at that level the protected member is to all intents and purposes private:
Class A --- protected foo()
Class B --- inherits from A: foo() effectively private at B level
Class C --- inherits from A: foo() effectively private at C level
--- bar() method calls instance of B to provide access to foo() via B
however this is not valid because foo() is private for B,
therefore C cannot call it
--- also has its own call to foo(): Valid call to its own private function
Hopefully this makes a bit more sense of the way that the visibility works at the different levels, I will look up some references once I get home tonight and have access to my books.