Date: Thu, 5 Jan 2023 17:15:27 -0500
On Thu, Jan 5, 2023 at 5:09 PM Frederick Virchanza Gotham <
cauldwell.thomas_at_[hidden]> wrote:
> On Thu, Jan 5, 2023 at 10:01 PM Brian Bi <bbi5291_at_[hidden]> wrote:
>
> > No.
> >
> > There's no legitimate reason to restrict what the author of B can make
> > one of its non-virtual functions do. As such, there should not be a
> > language-level mechanism for it.
>
> The following program fails to compile:
>
> struct A {
> virtual int Func(void) final { return 5; }
> };
>
> struct B : A {
> int Func(void) { return 6; }
> };
>
> int main(void)
> {
> B obj;
> }
>
> Note here that the person who wrote 'B' didn't necessarily know that
> 'A' had a virtual function called 'Func', but nonetheless 'B' is
> restricted in what it can do. So it won't be that much different
> restricting non-virtual functions also.
>
I think you meant to send this to the list, not to me.
Sure, if you declare a virtual method `final`, then you restrict what
derived classes can do, but the difference is that there's actually a
legitimate reason for the restriction. If I have
int foo(A& a) { return a.Func(); }
and `A::Func` is final, then the compiler can devirtualize the call. In
addition, the writer of this code can rely on the guarantee that `a.Func()`
has the same value and side effects as `a.A::Func()`. If any other
functions in `A` call `A::Func`, then they, too, can rely on such
guarantees.
On the other hand, if `Func` is non-virtual, then those guarantees already
hold; having the ability to prevent a derived class from declaring a method
with the same name does not strengthen them. As such, it is a restriction
that gives nothing in return.
cauldwell.thomas_at_[hidden]> wrote:
> On Thu, Jan 5, 2023 at 10:01 PM Brian Bi <bbi5291_at_[hidden]> wrote:
>
> > No.
> >
> > There's no legitimate reason to restrict what the author of B can make
> > one of its non-virtual functions do. As such, there should not be a
> > language-level mechanism for it.
>
> The following program fails to compile:
>
> struct A {
> virtual int Func(void) final { return 5; }
> };
>
> struct B : A {
> int Func(void) { return 6; }
> };
>
> int main(void)
> {
> B obj;
> }
>
> Note here that the person who wrote 'B' didn't necessarily know that
> 'A' had a virtual function called 'Func', but nonetheless 'B' is
> restricted in what it can do. So it won't be that much different
> restricting non-virtual functions also.
>
I think you meant to send this to the list, not to me.
Sure, if you declare a virtual method `final`, then you restrict what
derived classes can do, but the difference is that there's actually a
legitimate reason for the restriction. If I have
int foo(A& a) { return a.Func(); }
and `A::Func` is final, then the compiler can devirtualize the call. In
addition, the writer of this code can rely on the guarantee that `a.Func()`
has the same value and side effects as `a.A::Func()`. If any other
functions in `A` call `A::Func`, then they, too, can rely on such
guarantees.
On the other hand, if `Func` is non-virtual, then those guarantees already
hold; having the ability to prevent a derived class from declaring a method
with the same name does not strengthen them. As such, it is a restriction
that gives nothing in return.
-- *Brian Bi*
Received on 2023-01-05 22:15:40