c++ - 是否可以重载(影子)虚函数?

标签 c++ inheritance overriding overloading virtual-functions

我想隐藏基类的虚函数,并引入一个具有相同名称和相同签名(返回类型除外)的新虚函数。

类似于:

struct A {
  virtual int f() = 0;              // Newly introduced method: A::f.
};
struct B: public A {
  int f() final { return 1; }       // Overriding A::f.
};
struct C: public B {
  virtual double f() = 0;           // Newly introduced method C::f. It shadows A::f
};
struct D: public C {
  double f() final { return 2.0; }  // Overriding C::f.
};

我希望它的行为如下:

D d;
ASSERT( static_cast<D&>(d).f() == 2.0 );
ASSERT( static_cast<C&>(d).f() == 2.0 );
ASSERT( static_cast<B&>(d).f() == 1 );
ASSERT( static_cast<A&>(d).f() == 1 );

有可能实现这个目标吗?

任何版本的 C++ 标准都可以。

最佳答案

如果不改变函数签名(返回类型不属于函数签名的一部分),重载是不可能的。但是由于默认的函数参数,我们可以有不同的签名,但仍然使用相同数量的参数进行调用。使用 C++20 之类的东西 std::type_identity (尽管可以在任何标准中轻松实现),一旦可以编写

struct A {
  virtual int f(std::type_identity<int> = {}) = 0;
};
struct B: public A {
  int f(std::type_identity<int> = {}) final { return 1; }
};
struct C: public B {
  virtual double f(std::type_identity<double> = {}) = 0;
};
struct D: public C {
  double f(std::type_identity<double> = {}) final { return 2.0; }
};

每个重载现在都标有其返回类型,从而为每个重载提供不同的签名。但默认参数 {} 使得可以通过 f() 调用它们。并且由于名称隐藏,空参数列表的重载集不存在冲突。

通过这些修改,your set of assertions now passes .

关于c++ - 是否可以重载(影子)虚函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65774714/

相关文章:

java - Kotlin 数据类实现 Java 接口(interface)

c++ - c++调试:从控制台调试语句

c++ - 将对象传递给期望 shared_ptr 的函数而不实际共享所有权

c++ - 无法在c中获取当前时间

OOP 派生类和继承类的区别?

php - 什么是php中的函数重载和覆盖?

c++ - 在C++中使用静态方法实现工厂模式

java - 继承和通过方法传递参数

c++ - 可以将指向子对象的指针视为指向父对象的指针吗?

重写与隐藏基类方法时的 C# 作用域差异