C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::chimeric_ptr -- it's alive... it's ALIVE!

From: Magnus Fromreide <magfr_at_[hidden]>
Date: Thu, 27 Nov 2025 15:55:13 +0100
On Thu, Nov 27, 2025 at 11:46:05AM +0000, Frederick Virchanza Gotham via Std-Proposals wrote:
> On Thu, Nov 27, 2025 at 4:32 AM Thiago Macieira wrote:
> >
> > This is not a different problem. It's the same problem, based on the same
> > poorly-defined API. Why did someone need a base for each and every one of the
> > operations? Are they used in multiple places? Is there at least one class that
> > has one but not the rest of the bases? This seems to me that someone used a
> > C++ feature because they could, not because they needed it or because it was
> > good design.
>
>
> I don't work on the microscopes anymore but I can remember a lot of
> the code. I've changed a few names in the following code so as to
> avoid sharing secrets.
>
> The desktop PC software development kit (i.e. SDK) exposed a function
> that returned a pointer to an interface for a microscope, let's say:
>
> IMicroscope ConnectMicroscope( int model );
>
> You could pass it 1 for the Yellow microscope, 2 for the Green
> microscope, 3 for the Orange microscope and so on. Some microscope
> models only had the most basic features. Some had many many features.
> This SDK was developed over about 25 - 30 years through the life
> cycles of about half a dozen microscopes, and it became massive.
>
> The most feature-rich microscope was the Pink microscope. The class
> that managed it was defined something like:
>
> class Pink : public IMicroscope, public IUtility, public IDrift,
> public IIllumination, public IStage, public IEscape, public
> IObjective, public IDiagnostics, public IIris, public IPower, public
> IAsyncControl, public ICommsHandler {
> . . .
> };
>
> Each of those 12 base classes had maybe 6 - 10 virtual methods,
> thereabouts. The more basic microscopes only inherited from about 4 or
> 5 base classes. For example the base class 'IStage' might have been
> something like:
>
> class IStage {
> public:
> virtual void SetSpeed( float ) = 0;
>
> virtual float GetSpeed(void) = 0;
> virtual float GetSpeedMin(void) = 0;
> virtual float GetSpeedMax(void) = 0;
> };
>
> So these base classes weren't trivial. In fact the one that managed
> the objectives I think had two or three dozen methods.
>
> Now let's say I was to come along at a later stage, with the goal of
> writing a function that could safely prepare a microscope to be
> powered down and packaged for shipping. So in this function, I would
> move the stages to a safe place, I would cut the power circuit to the
> lights and motors (but not before cooling down the lightbulbs), I
> would reset the diagnostics, and so on. So I might write a function
> something like:
>
> void PrepareForShipping( std::chimeric_ptr< IStage, IPower,
> IIllumination, IDiagnostics, ICommsHandler > );
>
> So I think the question to be answered here is as follows. Which of
> the following is true, A or B?
> (a) I have used 'chimeric_ptr' to compensate for a bad design of
> class hierarchy
> (b) The class hierarchy is designed okay, and 'chimeric_ptr' is a
> new feature that makes it easier to deal with objects that are
> required to have two or more specific base classes
>
> I'm genuinely interested to hear opinions on this. I think it's a case
> of B, because I don't see anything wrong with the class hierarchy. Yes
> the hierarchy is complex, but that's because that problem being solved
> is complex. What I'm saying is that I don't think the class hierarchy
> is more complex that it needs to be.

Is this not the exact situation dynamic_cast was invented for?

Using dynamic_cast also have the advantage that you are explicit about
which interface you are working with so the whole ordering discussion
becomes irrelevant.

/MF

Received on 2025-11-27 14:55:18