下标运算符的 C++ 继承规则

Mar*_*ark 4 c++ inheritance overloading subscript operator-keyword

我有一个关于 C++ 中的下标运算符、重载和继承的问题。我很确定,如果您有一个具有多个函数重载的父类,那么子类可能只覆盖其中一个函数并继承其余函数。这似乎不适用于下标运算符。(我做了一个错误的假设。它确实与任何其他函数没有什么不同。)考虑以下代码:

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()]; 
}
Run Code Online (Sandbox Code Playgroud)

我希望它使用来自父级的下标运算符而不是导致错误。是否可以从父级继承一些重载的下标运算符并覆盖其他下标运算符?如果没有,有没有比这样做更好的解决方案:

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); }
};
Run Code Online (Sandbox Code Playgroud)

由于我可能会从父级继承很多地方,因此必须手动指定这样的功能对维护来说是不利的。谢谢你的想法。

Chr*_*ckl 5

在 C++ 中避免两件事:

  • 混合重载和覆盖。
  • 公共虚函数(如果它不是析构函数)。

保持您的基类重载运算符为非虚拟的,并让它们委托给具有不同名称的私有虚拟函数。

下面是一个例子:

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()]; 
}
Run Code Online (Sandbox Code Playgroud)

这种方法,也称为非虚拟接口惯用语,代表了基类的客户端和派生类的实现者之间关注点的良好分离。作为副作用,它还解决了您的编译问题。