简体   繁体   中英

C++ Override Pure Virtual Function with Function Pointer

If I have a pure virtual function can it be overriden with a function pointer? Scenario below (I'm aware that it's not 100% syntactically correct):

#include<iostream>
using namespace std;

class A {
    public:
        virtual void foo() = 0;
};

class B : public A {
    public:
        B() { foo = &B::caseOne; }
        void caseOne() { cout << "Hello One" << endl; }
        void caseTwo() { cout << "Hello Two" << endl; }
        void (B::*foo)();
        void chooseOne() { foo = &B::caseOne; }
        void chooseTwo() { foo = &B::caseTwo; }
};

int main() {
    B b;
    b.(*foo)();
}

EDIT: In case anyone's interested, here's how I accomplished what I wanted to do:

#include<iostream>
using namespace std;

class A {
    public:
        virtual void foo() = 0;
};

class B : public A {
    public:
        B() { f = &B::caseOne; }
        void caseOne() { cout << "Hello One" << endl; }
        void caseTwo() { cout << "Hello Two" << endl; }
        void (B::*f)();
        void chooseOne() { f = &B::caseOne; }
        void chooseTwo() { f = &B::caseTwo; }
        void foo() { (this->*f)(); }
};

int main() {
    B b;
    b.foo();
    b.chooseTwo();
    b.foo();
}

The output is:

Hello One
Hello Two

No. And you use this wrong. In your code you are trying to assign member-function pointer to function-pointer - it's cannot be compiled.

C++03 standard 10.3/2

If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name and same parameter list as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.

As @ForEveR said, your code cannot compile. However, since what you actually need is the ability of switching B 's implementation of foo in the runtime, we do have workaround:

#include <iostream>
using namespace std;

class A {
    public:
        virtual void foo() = 0;
};

class B : public A {
    private:
        void (B::*_f)();

    public:
        B() { chooseOne(); }

        void caseOne() {
            cout << "case one" << endl;
        }

        void caseTwo() {
            cout << "case two" << endl;
        }

        void chooseOne() { _f = &B::caseOne; }

        void chooseTwo() { _f = &B::caseTwo; }

        void foo() {
            (this->*_f)();
        }
};

int main(int argc, const char *argv[])
{
    A* b = new B();
    b->foo();
    ((B*)b)->chooseTwo();
    b->foo();
    return 0;
}

UPDATE :

Just found the OP added his answer in the question, which is almost the same as mine. But I think calling foo through pointer instead of instance object is better, for that can exhibit the effect of polymorphism. Besides, it's better to hide f as a private member function.

I think when compile time, the syntax can NOT be compiled. You should provide an override function with the certain name and same args list.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM