2

純粋仮想関数がある場合、関数ポインターでオーバーライドできますか? 以下のシナリオ (構文的に 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
4

3 に答える 3

2

@ForEveR が言ったように、コードはコンパイルできません。ただし、実際に必要なのは、ランタイムでBの の実装を切り替える機能であるため、次の回避策があります。foo

#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その上、非公開のメンバー関数として非表示にする方が良いです。

于 2013-02-01T07:23:26.063 に答える
2

いいえ、あなたはこれを間違って使用しています。あなたのコードでは、メンバ関数ポインタを関数ポインタに割り当てようとしています - コンパイルできません。

C++03 標準 10.3/2

仮想メンバー関数 vf がクラス Baseおよびクラス Derived で宣言され、Base から直接的または間接的に派生した場合、 Base ::vf と同じ名前と同じパラメーター リストを持つメンバー関数 vf が宣言され、Derived::vfも仮想であり (そのように宣言されているかどうかに関係なく)、Base::vf をオーバーライドします。

于 2013-02-01T06:52:51.253 に答える
0

コンパイル時に、構文をコンパイルできないと思います。特定の名前と同じ引数リストを持つオーバーライド関数を提供する必要があります。

于 2013-02-01T06:52:29.223 に答える