c++ - 仅在使用间接时调用虚函数——经典的早期绑定(bind)问题?

标签 c++ inheritance

我有一个接口(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);
}

Work with the code .

我希望 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";
    }
};

Demo

关于c++ - 仅在使用间接时调用虚函数——经典的早期绑定(bind)问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42588493/

相关文章:

c++ - auto using parens 可以表示函数原型(prototype)吗?

C++ 子类构造函数

Python 'object' 类型和继承

c# - 类型转换为基类

c++ - 使用 SWIG 用虚拟方法包装 C++ 类并在 python 中覆盖它们

c++ - 为什么 2 不 > 0 ?它是 <= 0,但不是 < 0,也不 == 0

c++ - 用于公开缓存数据的同步线程安全 API

c++ - std::promise 外部代码,异步取消

c++ - 为什么 static_cast 为同一对象提供不同的内存位置?

java - 涉及继承的代码片段