0

This is a true story of evolving code. We began with many classes based on this structure:

class Base
{
public:
    virtual void doSomething() {}
};

class Derived : public Base
{
public:
    void doSomething() override 
    {
        Base::doSomething(); // Do the basics

        // Do other derived things
    }
};

At one point, we needed a class in between Base and Derived:

class Base;
class Between : public Base;
class Derived : public Between;

To keep the structure, Between::doSomething() first calls Base. However now Derived::doSomething() must be changed to call Between::doSomething()...

And this goes for all methods of Derived, requiring search & replace to many many calls.

A best solution would be to have some this->std::direct_parent mechanism to avoid all the replacements and to allow easy managing of class topology.

Of course, this should compile only when there's a single immediate parent.

Is there any way to accomplish this? If not, could this be a feature request for the C++ committee?

gil_mo
  • 575
  • 1
  • 6
  • 27
  • It's not standard, but MSVC supports the `__super` keyword for that. See: https://learn.microsoft.com/en-us/cpp/cpp/super?view=msvc-170. – wohlstad Nov 24 '22 at 09:06
  • Could be great but indeed can't be used if not MSVC – gil_mo Nov 24 '22 at 11:07
  • No, see my first comment to the suggested answer below – gil_mo Nov 24 '22 at 14:06
  • The accepted answer in the above-mentioned question provides a history behind standardization effort for "inherited" keyword with a comment that it is unlikely to get standardized as it has been already dropped earlier for "too little gain for the cost". And this would be required to protect programmer from forgetting to define "super", "base" or inherited typedef. I don't believe you'll get better answer then that. – Tomek Nov 25 '22 at 07:45
  • Indeed. As for the "forgetting" part, a dedicated keyword would also protect you when you add a second direct base. In that case I'd expect a compilation error for "super" ambiguity. Without the keyword - no protection from this case. – gil_mo Nov 25 '22 at 13:15

2 Answers2

7

What I can suggest is parent typedef in Derived:

class Base
{
public:
    virtual void doSomething() {}
};

class Derived : public Base
{
private:
    typedef Base parent;
public:
    void doSomething() override 
    {
        parent::doSomething(); // Do the basics

        // Do other derived things
    }
};

Then after introduction of Between the only change needed in Derived is the change of the parent typedef:

class Derived : public Between
{
private:
    typedef Between parent;
public:
    void doSomething() override 
    {
        parent::doSomething(); // Do the basics

        // Do other derived things
    }
};
Tomek
  • 4,554
  • 1
  • 19
  • 19
  • 2
    I like the solution, but instead of typedef, I would use `using parent = Between;` (If you have code bases with templates that usually plays a bit nicer) – Pepijn Kramer Nov 24 '22 at 09:14
  • This is a sub-elegant solution, since it only solves one problem of the two: the multiple search-replace. It doesn't protect you if you forget to change your typedef - everything would build and you'd get errors at runtime. – gil_mo Nov 24 '22 at 11:21
  • Well, ideally it would be language element (like in Borland Pascal at some point, where there was `inherited` keyword). This unfortunately is highly unlikely as there is no good way to define it in multiple inheritance case. What you can try to do is inject base class via template which defines protected typedef to the base but it also has its drawbacks (the typedef proliferates to derived classes if not overridden). – Tomek Nov 24 '22 at 11:49
1

I think this question is related to: Using "super" in C++

I've seen projects, where the direct parent of the current class is mentioned as a "SUPER" typedef in the class header. This makes code-changes with new intermediate classes easier. Not bulletproof, but easier. Almost the same, as in the linked question.

Matti
  • 88
  • 1
  • 6