Hi,
The docu I have isn’t clear or doesn’t address this question: where do I need to put the declarations of inherited primitives ? Does it make a difference regarding dispatching ?
I’m talking of non-abstract primitives inherited publically.
Do we need to mention in the spec when we override a primitive, or is it enough to just put it in the package body ?
I’ve always put [not] overriding
in the spec, and not in the body, on the grounds (I suppose) that by the time you get to the body, you (the originator) know whether it’s overriding or not. I suppose it’d be a handy reminder.
Doesn’t the compiler complain if you don’t put it in the spec?
[Did you mean to post this on a different topic? the heading doesn’t seem to bear much relation to the post]
sorry, I must have picked up a draft with previous title.
Yes, right, it does complain without a declaration. Now the question is whether there’s a difference to put in the public or private part.
It is fine to override a primitive in the private part. If you override in the public part, then code that directly calls the routine (as opposed to reaching it via run-time dispatching) sees the formal parameter names and the defaults you specify. If you override in the private part, then code that directly calls the routine from outside the package sees the formal parameter names and defaults from the nearest ancestor that visibly declares/overrides the primitive, rather than whatever parameter names and defaults you specify in the private overriding.
Basically, a caller can only “see” the formal parameter names and default expressions from a subprogram declaration that is visible to them.
Ah… Thank you.
Because dispatching subprograms are subtype conformant and not fully conformant, the name of their parameters differ, which marginally affect name association (not sure how one could leverage that) but more importantly defaults also change. I can see that coming in handy.
I don’t know if I could ever have grasped what you explained from the RM on my own. But you primed me I could find more.
Hi Tucker, I’ve never provided an overriding in both public and private areas when I extend a tagged type. What would be the advantage to having certain public primitive ops defined by an ancestor be overridden in the private area by a descendant?
I think I’ve seen that done with controlled types, where you know that there must be Finalize
etc but you don’t need to see the declarations.
Since Finalize has no defaults nor is supposed to be called directly, I can’t what difference it would make either.
One reason to override in the private part is because the operation is not intended to be visible outside the defining package, so both the parent and the derived type only declare the operation in the private part. This usually only makes sense if the derived type is defined in a child package of the package where the parent is defined. Other reasons to override in the private part might be because a default expression in the overriding is intended for use only inside the package. But I will admit that such situations are relatively rare …