[Development] Should QObject::event() be protected or public?

André Somers andre at familiesomers.nl
Mon Mar 18 13:34:04 CET 2024


Hey,

On 18/03/2024 12:12, Giuseppe D'Angelo via Development wrote:
> Il 15/03/24 21:21, Jaroslaw Kobus via Development ha scritto:
>> To the point: we are talking here about decreasing the visibility of a
>> member function in a subclass.
>> The virtuality of the method isn't relevant I guess, is it?
>
> It is relevant, since that's the whole problem: since event() is a 
> virtual which is public in QObject, it's pointless to restrict it 
> further in a subclass, because you can always place the call 
> considering the object as-a QObject (=> upcast it) and bypass the 
> restriction.
>
> Therefore, when one creates a QObject subclass with an event() 
> override, then:
>
> * either they didn't know about the fact that it was public in 
> QObject, and thought it was protected/private (because virtual 
> functions should normally be protected), without think about the above 
> C++ """feature""" at all, etc. (mistake in good faith);
>
> * or they were *deliberately* trying to change the access level, i.e. 
> trying to *outsmart* C++, but that goes nowhere; making it more 
> restrictive simply doesn't work (can be bypassed by upcasting, breaks 
> generic code that codes against the interface, breaks subclasses).
>
While I know it's easy to work around, I sometimes find myself doing it 
anyway. To me, it signals what API is intended to be used in what way. 
That a class overrides `event`  (or any other public virtual method) 
does not mean that that method is then intended to be called by a user 
of the class as the type you defined. That you overwrote it may just be 
an implementation detail. I think the methods you expose as "public" on 
an API are quite important*. They signal how the user is supposed to use 
an instance of your class. If you have methods in there that are just 
implementation details, then those don't fit. These methods are meant to 
be called by parts of the system that don't see your type as the actual 
type, but as something more basic: a QObject in this case.

It's not a matter of "outsmarting" the compiler, or something like that. 
It's telling the user of the class which method he is supposed to focus 
on. I find myself doing these kinds of things for instance with QAIM, 
which as quite a big API to re-implement in some cases. Those are all 
public in the base class, but that does not mean that the person using 
my customized type should be fiddling with those methods: they are for 
consumption by views and proxy models and other bits that operate on 
QAIM instances. So, I tend to make these overridden methods protected 
instead, and only keep the higher-level methods that make sense in terms 
of the application API public.

You also seem to be overlooking that you can change the access level of 
all methods of the base class by not using public inheritance, but using 
protected or private. Those don't get much use, but I would say that 
it's an intentional feature.

Cheers,

André


*) And in the same way, that the "protected" section is the API 
available for someone subclassing your class.




More information about the Development mailing list