C++ 仅在使用间接寻址时调用虚拟函数—;经典的早期绑定问题?

C++ 仅在使用间接寻址时调用虚拟函数—;经典的早期绑定问题?,c++,inheritance,C++,Inheritance,我有三种不同的接口实现(求解方程组)。旧接口本质上是类中的voidfoo(int*f)。现在我想把它推广到一个例子,在这个例子中,我同时求解N系统。为此,我希望有一个接口voidfoo(int*f[N]) 在代码库中有一个定义接口的抽象类,然后从该类派生三个类。我想在不破坏现有代码的情况下添加我的泛化。因此,我考虑添加新接口,并将旧接口委托给新接口。这是我的压缩版本: #include <iostream> struct AbstractClass { /// Old in

我有三种不同的接口实现(求解方程组)。旧接口本质上是类中的voidfoo(int*f)。现在我想把它推广到一个例子,在这个例子中,我同时求解
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";
    }
};