我想隐藏基类的虚函数,并引入一个具有相同名称和相同签名(返回类型除外)的新虚函数。
类似于:
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/