【问题标题】:C++ Override Pure Virtual Function with Function PointerC++ 用函数指针覆盖纯虚函数
【发布时间】:2013-01-16 11:02:05
【问题描述】:

如果我有一个纯虚函数,可以用函数指针覆盖它吗?下面的场景(我知道它在语法上不是 100% 正确的):

#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)();
}

编辑:如果有人感兴趣,以下是我完成我想做的事情的方法:

#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();
}

输出是:

Hello One
Hello Two

【问题讨论】:

    标签: c++ oop inheritance function-pointers virtual-functions


    【解决方案1】:

    没有。而你用错了。在您的代码中,您试图将成员函数指针分配给函数指针 - 它无法编译。

    C++03 标准 10.3/2

    如果虚拟成员函数 vf 在类 Base 和 Derived 类中声明,则直接派生或 间接来自 Base,与 Base::vf 具有相同名称和相同参数列表的成员函数 vf 是 声明,然后 Derived::vf 也是虚拟的(无论它是否如此声明)并且它覆盖 Base::vf.

    【讨论】:

    • 谢谢。我已经编辑了我的代码以使用正确的(我认为)语法,以防其他人遇到这个问题。
    【解决方案2】:

    正如@ForEveR 所说,您的代码无法编译。但是,由于您真正需要的是在运行时切换Bfoo 实现的能力,我们确实有解决方法:

    #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;
    }
    

    更新

    刚刚发现OP在问题中添加了他的答案,这与我的几乎相同。但是我认为通过指针而不是实例对象调用foo更好,因为这样可以表现出多态的效果。此外,最好将f 隐藏为私有成员函数。

    【讨论】:

      【解决方案3】:

      我认为在编译时,无法编译语法。您应该提供具有特定名称和相同参数列表的覆盖函数。

      【讨论】:

        猜你喜欢
        • 2020-08-21
        • 2014-05-22
        • 2013-10-04
        • 2021-09-30
        • 2022-01-13
        • 1970-01-01
        • 2015-06-17
        • 2016-02-05
        • 2011-02-24
        相关资源
        最近更新 更多