我有三种不同的接口实现(求解方程组)。旧接口本质上是一个类中的void foo(int *f)
。现在我想将此概括为我同时解决N
系统的情况。为此我想要接口void foo(int *f[N]
)。
在代码库中有一个定义接口的抽象类,然后从该类派生出三个类。我想在不破坏现有代码的情况下添加我的概括。因此,我想添加新接口并将旧接口委托给新接口。这是我的压缩版本:
#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)
,然后转到Derived::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不与自动存储一起使用,因为函数调用在编译时绑定(早期绑定)?
这让我更接近解决方案,但我仍然需要触摸使用此库的所有代码。然而,这不是一个真正的选择,旧的东西必须继续工作。
我该怎么办(除了复制所有代码)?将此委托复制到每个派生类中是否足够?
答案 0 :(得分:2)
C ++中有一些称为name hiding的东西。基本上,当您在派生类中重写成员函数时,它会隐藏在基类中找到的所有其他重载。
这就是下面失败的原因:
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";
}
};