Simple inheritance in C++
I was going over some sample questions for an upcoming test, and this question is totally confusing me.
Consider the following code:
class GraduateStudent : public Student
{
...
};
If the word "public" is omitted, GraduateStudent
uses private inheritance, which means which of the following?
GraduateStudent
objects may not use methods ofStudent
.GraduateStudent
does not have开发者_如何学运维 access to private objects ofStudent
.No method of
GraduateStudent
may call a method ofStudent
.Only
const
methods ofGraduateStudent
can call methods ofStudent
.
Although this is a bare homework-ish question, I'm going to answer it because it is a terrible question. I would almost consider it a trick question, and it doesn't really make for a good test of knowledge.
The answer is 2. GraduateStudent does not have access to private objects of Student., except that this has nothing at all to do with private inheritance. Point 2 would be true whether or not the public
keyword were present, since derived classes never have access to the private members of their base classes, no matter how they inherit.
Private inheritance means essentially two things (as opposed to public inheritance):
All public methods of
Student
become private methods inGraduateStudent
. That means that if, for example,Student
has a public methodfoo()
, thenGraduateStudent
has a private methodfoo()
.The base class is "inaccessible", which means that polymorphism does not work. In layman's terms, this means that if
GraduateStudent
inherits privately fromStudent
, then you cannot treat aGraduateStudent*
as if it were aStudent*
(or aGraduateStudent&
as if it were aStudent&
).
It's possible that the author of the question also meant for point 1 to be a correct answer, but it is ambiguously worded. What does it mean that "GraduateStudent
objects may not use methods of Student
"? It's possible that the intent is for this to mean that you cannot call methods inherited from Student
on objects of type GraduateStudent
, like I wrote in the first point above, but the GraduateStudent
object itself, within its methods, can use methods of Student
.
For example:
class Student {
public:
void foo() {};
};
class GraduateStudent : Student {
public:
void bar()
{
foo(); // Legal
}
};
int main() {
GraduateStudent g;
g.bar(); // Legal
g.foo(); // Illegal
return 0;
};
1. GraduateStudent objects may not use methods of Student.
Not true, all GraduateStudent objects can use any public or protected members of Students (obviously private members are the exception here) internally. Also any outsider using these objects cannot access the base Student class of the object, the access to the base class must happen within the context of the GraduateStudent methods.
2. GraduateStudent does not have access to private objects of Student.
Yes
3. No method of GraduateStudent may call a method of Student.
Not true
4. Only const methods of GraduateStudent can call methods of Student.
Nope, there's no distinction made on const members having more access to the base class than non-const members would have.
The only correct answer that I see is 2, but that does not depend on whether GraduateStudent
inherits from Student
privately or publicly.
Private inheritance means that it is private knowledge that GraduateStudent
is a Student
, so only friends of GraduateStudent
and GraduateStudent
members can static_cast
GraduateStudent&
to Student&
and GraduateStudent*
to Student*
, access public or protected member variables of Student
, and call public or protected member functions of Student
.
See: http://www.parashift.com/c++-faq-lite/private-inheritance.html
First: the inheritance access specifier does not modify the way Derived
interacts with Base
, it modifies the way the world can treat a Derived
object as if it were a Base
.
Consider:
struct A{};
struct B: xxxx A
{
friend void friendly();
};
struct C: B {};
void outsider();
A very simple table: I summarize which zones of A
can be accessed by the various actors.
xxxx public protected private
B pub/prot pub/prot pub/prot
friendly pub/prot pub/prot pub/prot *
C pub/prot pub/prot --
outsider pub -- --
Note (*): A friend has the same rights that the object itself, no surprise there.
A simple rule of thumb is to consider that the inheritance access specifier overrides the access specifiers of the base class if they are looser.
Since nothing is looser than public
, it does not change anything. protected
means that the public
section of the Base
becomes protected
, and private
means that the public
and protected
sections become private
.
精彩评论