Date: Mon, 7 Nov 2022 13:39:47 -0500
On Mon, Nov 7, 2022 at 11:24 AM Paul Fee via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>
> The "final" and "override" specifiers can be useful to ensure code using
> inheritance is implemented as expected. However there are some gaps where
> I find some features lacking, I can't express some approaches nor get the
> compiler to confirm my assumptions. [...]
> Would it be reasonable to enhance the set of specifiers so that more
> scenarios can be expressed, allowing the compiler to confirm if the
> developer's assumptions are correct? For example:
>
> * function must/must not override a base class function
> * function must/must not be part of a group of overloads
> * function must/must not be virtual
>
All of these scenarios are handled, as long as you follow the simple best
practices for OOP code in C++11-and-later. I believe the Core Guidelines
cover this
<https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rh-override>,
as does Scott Meyers and of course myself. ;)
The rules are:
- Use `virtual` (only) in base classes.
- Use `override` (only) in derived classes.
- That's all.
Your specific scenarios:
- This function must override a base-class function: That's just `int f()
override;`. Foolproof even if you don't follow the guidelines.
- This function must NOT override a base-class function: That's `int
f();`. Compile with `-Werror=suggest-override`.
- This function must be virtual: That's either `virtual int f();` or `int
f() override`, depending on if you're introducing or overriding `f`.
Compile with `-Werror=suggest-override`.
- This function must not be virtual: That's `int f();` Compile with
`-Werror=suggest-override`.
- This function must (not) be part of a group of overloads: That's not
something you want in C++. *Every* function is part of an overload set of
*some* cardinality; sometimes that cardinality just happens to be 1. Titus
Winters says <https://www.youtube.com/watch?v=xTdeZ4MxbKo&t=653s>, "The
unit of API design is the overload set."
If you really want to segregate public (overloadable) APIs from private
(overridable) implementations, may I suggest the Non-Virtual Interface
Idiom. :) I use it exclusively, and it's great. I have some training
material on it, and it was also covered in Jon Kalb's "Back to Basics:
Object-Oriented Programming," <https://www.youtube.com/watch?v=32tDTD9UJCE>
among other places.
–Arthur
std-proposals_at_[hidden]> wrote:
>
> The "final" and "override" specifiers can be useful to ensure code using
> inheritance is implemented as expected. However there are some gaps where
> I find some features lacking, I can't express some approaches nor get the
> compiler to confirm my assumptions. [...]
> Would it be reasonable to enhance the set of specifiers so that more
> scenarios can be expressed, allowing the compiler to confirm if the
> developer's assumptions are correct? For example:
>
> * function must/must not override a base class function
> * function must/must not be part of a group of overloads
> * function must/must not be virtual
>
All of these scenarios are handled, as long as you follow the simple best
practices for OOP code in C++11-and-later. I believe the Core Guidelines
cover this
<https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rh-override>,
as does Scott Meyers and of course myself. ;)
The rules are:
- Use `virtual` (only) in base classes.
- Use `override` (only) in derived classes.
- That's all.
Your specific scenarios:
- This function must override a base-class function: That's just `int f()
override;`. Foolproof even if you don't follow the guidelines.
- This function must NOT override a base-class function: That's `int
f();`. Compile with `-Werror=suggest-override`.
- This function must be virtual: That's either `virtual int f();` or `int
f() override`, depending on if you're introducing or overriding `f`.
Compile with `-Werror=suggest-override`.
- This function must not be virtual: That's `int f();` Compile with
`-Werror=suggest-override`.
- This function must (not) be part of a group of overloads: That's not
something you want in C++. *Every* function is part of an overload set of
*some* cardinality; sometimes that cardinality just happens to be 1. Titus
Winters says <https://www.youtube.com/watch?v=xTdeZ4MxbKo&t=653s>, "The
unit of API design is the overload set."
If you really want to segregate public (overloadable) APIs from private
(overridable) implementations, may I suggest the Non-Virtual Interface
Idiom. :) I use it exclusively, and it's great. I have some training
material on it, and it was also covered in Jon Kalb's "Back to Basics:
Object-Oriented Programming," <https://www.youtube.com/watch?v=32tDTD9UJCE>
among other places.
–Arthur
Received on 2022-11-07 18:39:59