C ++ inheritance rules for substring operator

I have a question regarding the index operator, overloading and inheritance in C ++. I am sure that if you have a parent class with multiple function overloads, then the child can only override one of the functions and inherit the rest. The same doesn't seem to be the case for the indexing operator. (I made a bad guess. This is really no different from any other function.) Consider the following code:

struct A {};
struct B {};

struct Parent
{
   virtual ~Parent() {}
   virtual int operator[](A index) { return -1; }
   virtual int operator[](B index) { return -2; }
};

struct Child : public Parent
{
   virtual int operator[](B index) override { return -3; }
};

int main()
{
   // error: no match for 'operator[]' (operand types are 'Child' and 'A')
   return Child()[A()]; 
}

      

I would expect it to use the index operator from the parent instead of throwing an error. Is it possible to inherit some of the overloaded index operators from the parent and override others? If not, is there a better solution than doing:

struct Child : public Parent
{
    virtual int operator[](B index) override { return -3; }
    // Force it to use the parent method
    virtual int operator[](A index) override { return Parent::operator[](index); }
};

      

Since I have potentially inherited a lot of places from the parent, and it is bad for maintenance to manually specify such functions. Thanks for your ideas.

+3


source to share


1 answer


Avoid two things in C ++:

  • Overload mixing and overriding.
  • Public virtual functions (if not a destructor).

Keep the overloaded base class operators non-virtual and pass them private virtual functions with different names.



Here's an example:

struct A {};
struct B {};

struct Parent
{
   virtual ~Parent() {}
   int operator[](A index) { return withA(index); }
   int operator[](B index) { return withB(index); }
private:
   virtual int withA(A index) { return -1; }
   virtual int withB(B index) { return -2; }
};

struct Child : public Parent
{
private:
   virtual int withB(B index) override { return -3; }
};

int main()
{
   return Child()[A()]; 
}

      

This approach, also known as a non-virtual interface initial , represents a good separation of concerns between base class clients and derived class developers. It also solves the compilation problem as a side effect.

+4


source







All Articles