C++ 仅在使用间接寻址时调用虚拟函数—;经典的早期绑定问题?
我有三种不同的接口实现(求解方程组)。旧接口本质上是类中的voidfoo(int*f)。现在我想把它推广到一个例子,在这个例子中,我同时求解C++ 仅在使用间接寻址时调用虚拟函数—;经典的早期绑定问题?,c++,inheritance,C++,Inheritance,我有三种不同的接口实现(求解方程组)。旧接口本质上是类中的voidfoo(int*f)。现在我想把它推广到一个例子,在这个例子中,我同时求解N系统。为此,我希望有一个接口voidfoo(int*f[N]) 在代码库中有一个定义接口的抽象类,然后从该类派生三个类。我想在不破坏现有代码的情况下添加我的泛化。因此,我考虑添加新接口,并将旧接口委托给新接口。这是我的压缩版本: #include <iostream> struct AbstractClass { /// Old in
N
系统。为此,我希望有一个接口voidfoo(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);
}
看起来派生对象并没有真正继承我想要的方法
使用带有指向基类指针的运行时多态性确实有效,但是:
AbstractClass *pd = new Derived();
int *a = nullptr;
pd->foo(a);
delete pd;
我真的不明白为什么没有指针它就不能工作。vtable不用于自动存储,因为函数调用是在编译时绑定的(早期绑定)
这让我离解决方案更近了一点,但我仍然需要接触使用这个库的所有代码。然而,这不是一个真正的选择,旧的东西必须继续工作
对此我能做些什么(除了复制所有代码)?将这个委托复制到每个派生类是否足够?< P> >在C++中有一些已知的东西。基本上,当您重写派生类中的成员函数时,它会隐藏基类中的所有其他重载 这就是以下失败的原因:
Derived d;
int *a;
d.foo(a);
及以下工程:
AbstractClass *pd = new Derived();
int *a = nullptr;
pd->foo(a);
因为带指针的foo
重载位于AbstractClass
中,但隐藏在派生的
中
您可以使用
使这些重载可见
struct Derived : public AbstractClass {
using AbstractClass::foo;
void foo(int *f[2]) override {
std::cout << "Derived::foo(int *f[2])\n";
}
};
struct派生:公共抽象类{
使用AbstractClass::foo;
void foo(int*f[2])覆盖{
std::cout虚拟函数只有在通过指针或引用调用时才会表现出多态性。这就是指定语言的方式。您能将其累积到coliru.stacked-crooked.com或类似网站中,让我们用您的代码进行实验吗?@πάνταῥεῖ: 我已经添加了一个到你提到的网站的链接。这就是你的意思吗?这就解释了情况!然后解决方案是将重载(仅24行)复制到每个派生类中。@MartinUeding,不。不要复制整个重载。请参阅我的更新答案。这很好,我会使用它!
struct Derived : public AbstractClass {
using AbstractClass::foo;
void foo(int *f[2]) override {
std::cout << "Derived::foo(int *f[2])\n";
}
};