You Convey To Know : Interfaces Together With Diamonds
class IPoint {
public:
virtual void SetLocation(const Point2& location)=0;
};
class IPoint_Heading : world virtual IPoint {
public:
virtual void SetHeading(double heading)=0;
};
I derive my point-heading from the signal because it makes the interface to a greater extent than useful for clients. Becasue ALL point-headings MUST BE points, clients tin only laid the place of a point-heading too purpose it similar a signal without having to practice dynamic casting too failure-checking. So that seemed good.
Why is it virtual? Well, here's why:
class WED_Point : world virtual IPoint {
public:
virtual void SetLocation(const Point2&) p;
};
class WED_Point_Heading : world WED_Point {
public:
virtual void SetHeading(double heading);
};
Basically I inherit the implementation of my signal into my point-with-heading to avoid recoding points. If IPoint isn't a virtual base of operations class, so the implementation of SetLocation doesn't apply to WED_Point_Heading.
Now earlier I'll become on, let's assay that fact inward to a greater extent than detail. It is a surprising detail. You mightiness think: "well, WED_Point_Heading derives from WED_Point whichi implements SetLocation, what else would I need?" That's what I idea until I tried it, too so when GCC rejected it read the C++ spec.
The work is simple: given a derived shape amongst 2 bases (B1 too B2), a virtual percentage inward B1 cannot supply an override for B2. (I don't come across whatsoever C++ implementation argue why the linguistic communication couldn't operate that way, e.g. it is possible to create this construction inward memory, but my approximate is that the ensuing chaos of mixing inward 2 unrelated bases too having 1 alter the guts of the other would move worse than what nosotros accept now, yesteryear a lot.)
The argue that the purpose of IPoint every bit a virtual base of operations solves this work is becasue WED_Point_Heading exclusively has one IPoint. The compiler merges the IPoint sub-object too hence WED_Point's overrides apply everywhere, because they're non existence copied from 1 base of operations to another, they're existence applied to 1 virtual base of operations too in that place is exclusively 1 virtual base.
Now I tend to enjoin that if you lot accept an inheritence diamond you've likely already screwed up, too this illustration is no exception. The existent work hither is the purpose of inheritence of implementation to larn code reuse. The existent agency to unravel this is:
- Define 2 non-virtual, non-polymorphic implementation classes (point-guts, heading-guts) that supply the truthful run-time implementations of the "SetLocation" code too "SetHeading" code.
- Derive WED_Point_Heading exclusively from IPoint_Heading.
- Use those same guts inward WED_Point too WED_Point_Heading. Because the mutual implementation has been factored out, the exclusively "code duplication" is the calling of the mutual implementation. I would enjoin this is non fifty-fifty code duplication, but code disambiguation (a careful description of how nosotros desire to map our interface hierarchy onto a laid of reusable implementation pieces.