我有一个接口(interface)的三种不同实现(求解方程组)。旧接口(interface)本质上是一个类中的 void foo(int *f)
。现在我想将其推广到我同时解决 N
系统的情况。为此,我想要接口(interface) void foo(int *f[N]
).
在代码库中有一个定义接口(interface)的抽象类,然后从该类派生出三个类。我想在不破坏现有代码的情况下添加我的概括。因此我想到了添加新接口(interface)并将旧接口(interface)委托(delegate)给新接口(interface)。这是我的压缩版本:
#include <iostream>
struct AbstractClass {
/// Old interface, needs to be retained.
virtual void foo(int *f) {
std::cout << "AbstractClass::foo(int *f)\n";
int *a[2] = {f, nullptr};
foo(a);
}
/// New interface.
virtual void foo(int *f[2]) {
std::cout << "AbstractClass::foo(int *f[2])\n";
}
};
struct Derived : public AbstractClass {
/// New interface.
void foo(int *f[2]) override {
std::cout << "Derived::foo(int *f[2])\n";
}
};
int main(int argc, char **argv) {
// Code using the old interface.
Derived d;
int *a;
d.foo(a);
}
我希望 d.foo(a)
的调用会转到继承的 Derived::foo(int *f)
并从那里转到 派生::foo(int *f[2])
。但是,g++
6.3 为我提供了以下内容(在 C++11 模式下):
inheritance-test.cpp: In function 'int main(int, char**)':
inheritance-test.cpp:31:12: error: no matching function for call to 'Derived::foo(int*&)'
d.foo(a);
^
inheritance-test.cpp:21:10: note: candidate: virtual void Derived::foo(int**)
void foo(int *f[2]) override {
^~~
inheritance-test.cpp:21:10: note: no known conversion for argument 1 from 'int*' to 'int**'
看起来派生对象并没有真正继承我想要的方法。
不过,使用带有指向基类指针的运行时多态性确实有效:
AbstractClass *pd = new Derived();
int *a = nullptr;
pd->foo(a);
delete pd;
我真的不明白为什么没有指针它就不能工作。 vtable 没有使用自动存储,因为函数调用在编译时绑定(bind)(早期绑定(bind))?
这让我离解决方案更近了一点,但我仍然需要接触使用该库的所有代码。然而,这并不是一个真正的选择,旧的东西必须继续工作。
我能做些什么(除了复制所有代码)?将此委托(delegate)复制到每个派生类中就足够了吗?
最佳答案
有一种叫做 name hiding 的东西在 C++ 中。基本上,当您重写派生类中的成员函数时,它会隐藏基类中发现的所有其他重载。
这就是下面失败的原因:
Derived d;
int *a;
d.foo(a);
下面的作品:
AbstractClass *pd = new Derived();
int *a = nullptr;
pd->foo(a);
因为带指针的foo
重载在AbstractClass
中,但隐藏在Derived
中。
您可以使用 using
使这些重载可见。
struct Derived : public AbstractClass {
using AbstractClass::foo;
void foo(int *f[2]) override {
std::cout << "Derived::foo(int *f[2])\n";
}
};
关于c++ - 仅在使用间接时调用虚函数——经典的早期绑定(bind)问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42588493/