On Tue, 03 Feb 2004 09:43:19 +0100, Dag Henriksson wrote:
"Uncle Bob (Robert C. Martin)" <u.*************@objectmentor.com> skrev
i meddelandet news:6j********************************@4ax.com...
No, probably because it won't compile. You can't make a derivative
member less accessible than a base member.
What do you mean by that? You certainly can do:
class B
{
public:
virtual void foo() {}
};
class D : public B
{
private:
virtual void foo() {}
};
You must have meant something else, but what?
Actually, the original example does not compile. I tried it to see what
sort of error it might generate and my compiler got a problem with the
virtual function table. However, I think you missed the point of Robert
Martins comment.
It is not a syntactic rule of C++ that you should not make a baes class
public member private in a derived class, but an OOP principle that you
should not make the interface of a derived class a strict subset of the
interface of the base class. Violating this principle can result in two
undesirable outcomes:
1. Either code that does not compile like the original example because of
the compiler being unable to resolve function references.
2. Code that compiles, like your example, and produces bad results.
What are bad results? If we flesh out your classes like this:
class B
{
public:
virtual void foo() { cout <<"Base" << endl;}
};
class D : public B
{
private:
virtual void foo() { cout <<"Derived" << endl;}
};
so we can see which version is being called, then the code
int main() {
D *d = new D();
B *b = d;
b->foo();
// d->foo(); this line does NOT compile
}
}
produces the output "Derived" when it runs.
We have broken the interface of B (or D -- take your pick). We can have
broken encapsulation for d and we do not get the expected behavior. The
problem is that looking at the combination of inheritance and access
restriction means that the use of the base class pointer makes the
reference to foo() ambiguous. The compiler chose one option, I may have
intended another.
Java, on the other hand, has opted to make violating this OOP principle
impossible by enforcing it with a syntactic constraint -- if you tried to
compile this code in Java, it would not but would generate the error
"Cannot reduce the visibility of the inherited method from base".
I think Robert Martin's comment still stands but perhaps I would have
said:
No, probably because it won't compile. You shouldn't make a derivative
member less accessible than a base member.
I think the point to remember about C++, and any programming language for
that matter, is that just because the language allows you to do something
does not mean that it is good code. I would never allow any code like your
example to be used in any project I was working on because of the
potential for a down the road disaster. ("Gee, it always worked before
without any problems...").
--
..................................................
2 + 2 = 5 (for sufficiently large values of 2)
Rod Davison - Critical Knowledge Systems Inc.