非虚拟基础的多态成员类

Mar*_*mus 5 c++ polymorphism arduino type-erasure dynamic-dispatch

First if all, of the polymorphism answers I find, it's always like "if the base function is not virtual and the derived object is stored in a pointer of type base, then you cannot call the derived function". But they never tell you what to do when you want to do exactly that. And that's what I need to do.

I have a base class B that I have no control over. It's open source (TwoWire from Arduino library) and it will not work for others if I make local modifications.

I have a derived class D and a user class U that I both have control over.

In effect, I want the user to use my class U transparently with either a B or a D as parameter, store it in a member, and use it in member functions.

My futile attempt before learning virtual is required on the base class:

#include <iostream>

using namespace std;

class B {
public:
    void foo() { cout << "base foo\n"; };
};

class D : public B {
public:
    void foo() { cout << "derived foo\n"; };
};

class U {
public:
    U(B *b) : b(b) { }
    void work() { b->foo(); }
private:
    B *b;
};

int main() {
    B b; U u1{&b}; u1.work(); // "base foo"
    D d; U u2{&d}; u2.work(); // I need this to somehow print "derived foo"
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

I could solve this by making an abstract wrapper class and two sub-classes that wrap either B or D, but that would bring the total number of custom classes to 5. I'm hoping for a solution of just 2 custom classes (or at most 3).

N.B. I'm just starting to learn C++, coming from Java

L. *_* F. 3

virtual由于不可能创建成员函数,因此您必须使用类型擦除来模拟动态分派:

#include <functional>

class U {
public:
    template <class C>
    U(C* p)
        : f{[p]{ p->foo(); }}
    {
    }
    void work()
    {
        f();
    }
private:
    std::function<void()> f;
};
Run Code Online (Sandbox Code Playgroud)

现场演示

请注意,Java 中的函数默认是虚拟的。不是在 C++ 中。