From: Jerry Coffin on
In article <hfrtl6$33n$1(a)news.eternal-september.org>, alfps(a)start.no
says...
>
> * Jerry Coffin:
> > as Herb Sutter argued years ago[1], there are actually pretty good
> > reasons for virtual functions to be private or protected.
>
> It's just stupid to have virtual functions private except in some very special
> cases. You loose the ability to assert that you're overriding something
> existing. And you introduce a bug-vector or at least a dang-again-vector, since
> whatever's introduced up in some base class, even though not accessible to you,
> can be inadvertently overridden by you.

Well, I'm certainly not going to argue that protected isn't a better
choice. At least from the viewpoint of the situation at hand, it
makes no difference either way.

--
Later,
Jerry.
From: Kaz Kylheku on
On 2009-12-10, Alf P. Steinbach <alfps(a)start.no> wrote:
> * Jerry Coffin:
>> as Herb Sutter argued years ago[1], there are actually pretty good
>> reasons for virtual functions to be private or protected.
>
> It's just stupid to have virtual functions private except in some very special
> cases.

It seems silly, but not for these reasons.

The idea makes sense that a set of virtual functions represent an
implementation strategy, which is not supposed to be invoked directly.
So far so good.

The problem is that all of the overriding derived classes have to voluntarily
uphold this decision. Any derived class can flip the access on the virtual
by defining a public version. So then if you have an object of that type,
you can call the virtual---but, inconsistently, you cannot call that
virtual through a base class reference.

In a pointer-to-implementation design, it's easily enforced. The virtuals can
be public, for all you care, but only the proxy object has access to the
implementation object which has those virtuals.

> You loose the ability to assert that you're overriding something
> existing.
>
> And you introduce a bug-vector or at least a dang-again-vector, since
> whatever's introduced up in some base class, even though not accessible to you,
> can be inadvertently overridden by you.

All these problems have nothing to do with access on virtual functions.

You cannot assert that you are overriding something existing, (or that you are
/not/ overriding something existing), because that feature is missing from all
dialects of C++ through C++98, and that's that.

The problem of inadvertent overriding is being addressed in C++0x
with [[base_check]], [[override]] and [[hiding]].
From: Alf P. Steinbach on
* Kaz Kylheku:
> On 2009-12-10, Alf P. Steinbach <alfps(a)start.no> wrote:
>> * Jerry Coffin:
>>> as Herb Sutter argued years ago[1], there are actually pretty good
>>> reasons for virtual functions to be private or protected.
>> It's just stupid to have virtual functions private except in some very special
>> cases.
>
> It seems silly, but not for these reasons.

You forgot to add any reasoning to that assertion, but anyway, to me it does
seem silly for those reasons that I gave and you quote below. That your
impression is different might be because you've not completely grokked the
issues. Or perhaps you have a higher tolerance of silliness than me.


> The idea makes sense that a set of virtual functions represent an
> implementation strategy, which is not supposed to be invoked directly.
> So far so good.
>
> The problem is that all of the overriding derived classes have to voluntarily
> uphold this decision. Any derived class can flip the access on the virtual
> by defining a public version. So then if you have an object of that type,
> you can call the virtual---but, inconsistently, you cannot call that
> virtual through a base class reference.

That's an extra point, but it's only valid when the derived class programmer
actively breaks the rules.

I didn't think of that.

It's not practically significant in C++, because the language is of such
complexity that the programmers are generally not novices; they don't go around
changing access levels willy-nilly.


> In a pointer-to-implementation design, it's easily enforced. The virtuals can
> be public, for all you care, but only the proxy object has access to the
> implementation object which has those virtuals.
>
>> You loose the ability to assert that you're overriding something
>> existing.
>>
>> And you introduce a bug-vector or at least a dang-again-vector, since
>> whatever's introduced up in some base class, even though not accessible to you,
>> can be inadvertently overridden by you.
>
> All these problems have nothing to do with access on virtual functions.

You forgot to add any reasoning to this assertion also.

But since it's plainly false there's nothing more to be said about that.


> You cannot assert that you are overriding something existing, (or that you are
> /not/ overriding something existing), because that feature is missing from all
> dialects of C++ through C++98, and that's that.

Nobody's said that you can assert that you're overriding, so that's a straw man
argument (even though it's not clear what your argument is about!). But even so,
even though it apparently isn't relevant to anything, your statement that one
cannot assert that one is overriding is very dubious, as are all statements
about non-existence. One would need a proof of non-existence.

The statement that you cannot assert that you're not overriding something
existing is, on the other hand, simply false.

Because it's very simple to assert that a base class method with compatible
arguments exists, or not.


> The problem of inadvertent overriding is being addressed in C++0x
> with [[base_check]], [[override]] and [[hiding]].

Goodie.


Cheers & hth.,

- Alf
From: Kaz Kylheku on
On 2009-12-11, Alf P. Steinbach <alfps(a)start.no> wrote:
>> On 2009-12-10, Alf P. Steinbach <alfps(a)start.no> wrote:
>>> You loose the ability to assert that you're overriding something
>>> existing.

[ ... ]

> Nobody's said that you can assert that you're overriding, so that's a straw man

?

Whatever.
From: Kaz Kylheku on
On 2009-12-11, Alf P. Steinbach <alfps(a)start.no> wrote:
> * Kaz Kylheku:
>> On 2009-12-11, Alf P. Steinbach <alfps(a)start.no> wrote:
>>>> On 2009-12-10, Alf P. Steinbach <alfps(a)start.no> wrote:
>>>>> You loose the ability to assert that you're overriding something
>>>>> existing.
>>
>> [ ... ]
>>
>>> Nobody's said that you can assert that you're overriding, so that's a straw man
>>
>> ?
>
> You're quoting the wrong context.
>
> In my first statement, the meaning of "overriding something existing" which I
> said one can do, was with the accent on the something existing, otherwise
> there'd be no point in adding those words; you know that you're overriding,
> you're asserting that the func you're overriding does exist in base class, and
> that assertion serves as documentation and guards against code changes.

Okay, can you show how you are coding that?

If we simply declare a function in a class which has bases, we don't
know whether or not that function is virtual; it could match a virtual
function in one of the bases, thereby inheriting that attribute
and overriding.

If we explicitly make it virtual, we still don't know whether or not
something is being overridden, or whether it's a new virtual.

We can inspect all the bases when we are coding this, but tomorrow, they
can change; someone can add a virtual function to a base such that
we already have an overriding function in the derived class.

If there is a way of writing assertions for this sort of thing, or
anyting at all related to overriding or not-overriding; that could be
useful. (Compile time, or run-time).