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

标签 c++ inheritance overloading operator-keyword subscript

我有一个关于 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()]; 
}

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

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); }
};

因为我可能从父级继承了很多地方,而且必须手动指定这样的功能对于维护来说是不好的。感谢您的想法。

最佳答案

在 C++ 中避免两件事:

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

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

这是一个例子:

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()]; 
}

此方法也称为 Non-Virtual Interface Idiom , 表示基类的客户和派生类的实现者之间的关注点很好地分离。它还作为副作用解决了您的编译问题。

关于下标运算符的 C++ 继承规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43943094/

相关文章:

c++ - 通过函数结束程序?

用于处理 a = b + c 的 C++ 运算符语法,无需显式复制 "a.data_ptr"中的数据

java - 如果我将一个子类转换为它的父类(super class),并调用一个在子类中被覆盖的方法,它会执行被覆盖的方法还是原始方法?

java - 扩展一个包含对自身列表的引用的类

c++ - 调用和重载模板函数

c++ - 使用 CMake 编译带有链接 dll 的应用程序。需要查看工作示例

c++ - 为多个类实例维护 shared_ptr 的静态列表

asp.net-mvc - Entity Framework - 选择特定列并返回强类型而不丢失强制转换

c++ - 重载运算符中的段错误 =

c++ - 当参数是引用时,可变参数模板构造函数选择失败