1

特定のインスタンスのみの関数をオーバーライドする方法があるかどうか疑問に思っていました。たとえば、

class A
{
public:
    ...
    void update();
    ...
}

int main()
{
    ...
    A *first_instance = new A();
    // I want this to have a specific update() function.
    // ex. void update() { functionA(); functionB(); ... }

    A *second_instance = new A();
    // I want this to have a different update() function than the above one.
    // ex. void update() { functionZ(); functionY(); ...}

    A *third_instance = new A();
    // ....so on.
    ...
}

これを達成する方法はありますか?

4

5 に答える 5

10

仮想関数はまさにあなたが望むものだと思います。仮想関数を使用すると、同じタイプの異なるインスタンスが異なる機能を持つことができますが、基本クラスを継承する必要があります。例えば

class A
{
    public:
        ...
        virtual void update()
        {
            std::cout << "Class A\n";
        }
        ...
};

class B: public A
{
    public:
        virtual void update()
        {
            std::cout << "Class B\n";
        }
};

class C: public A
{
    public:
        virtual void update()
        {
            std::cout << "Class C\n";
        }            

};

int main()
{
    ...
    A *first_instance = new A();
    // I want this to have a specific update() function.
    // ex. void update() { functionA(); functionB(); ... }

    A *second_instance = new B();
    // I want this to have a different update() function than the above one.
    // ex. void update() { functionZ(); functionY(); ...}

    A *third_instance = new C();
    // ....so on.
    ...
}

上記のコードの各インスタンスは、異なる更新関数をバインドします。

また、関数ポインターを使用して要件を実装することもできますが、お勧めしません。例えば

class A
{
    public:
        A(void(*u)())
        {
            this->update = u;
        }
        ...
        void (*update)();
};

void a_update()
{
    std::cout << "update A\n";
}

void b_update()
{
    std::cout << "update B\n";
}

void c_update()
{
    std::cout << "update C\n";
}

int main()
{
    ...
    A first_instance(a_update);
    // I want this to have a specific update() function.
    // ex. void update() { functionA(); functionB(); ... }

    A second_instance(b_update);
    // I want this to have a different update() function than the above one.
    // ex. void update() { functionZ(); functionY(); ...}

    A third_instance(c_update);
    // ....so on.
    ...
}

希望が役立ちます!

于 2013-08-11T10:46:11.347 に答える
5

functionクラスで開催します。

#include <iostream>
#include <functional>

using namespace std;

class Foo
{
public:
    Foo(const function<void ()>& f) : func(f)
    {
    }

    void callFunc()
    {
        func();
    }
private:
    function<void ()> func;
};

void printFoo() { cout<<"foo"<<endl; }
void printBar() { cout<<"bar"<<endl; }

int main()
{
    Foo a(printFoo);
    Foo b(printBar);
    a.callFunc();
    b.callFunc();
}
于 2013-08-11T10:59:03.657 に答える
0

ローカルクラスを使用できますが、個人的には、他の回答で言及されている「クラス内の機能を保持する」アプローチの方が優れていると思います。doFuncメンバー変数に保持されている関数からは不可能な、基本クラスの内部にアクセスする必要がある場合にのみ、次のアプローチをお勧めします。

class ABase {
public:
    void Func () { this->doFunc (); }
private:
    virtual void doFunc () = 0;
public:
    virtual ~ABase () { }
};

ABase* makeFirstA () {
    class MyA : public ABase {
        virtual void doFunc () { std::cout << "First A"; }
    };
    return new MyA;
}

ABase* makeSecondA () {
    class MyA : public ABase {
        virtual void doFunc () { std::cout << "Second A"; }
    };
    return new MyA;
}

int main () {
    std::shared_ptr<ABase> first (makeFirstA ());
    std::shared_ptr<ABase> second (makeSecondA ());
    first->Func ();
    second->Func ();
}

デザイン パターンの観点から見ると、「ローカル クラス」アプローチはテンプレート メソッド patternを実装し、「メンバー変数に関数を保持する」アプローチは戦略 patternを反映します。どちらがより適切かは、何を達成する必要があるかによって異なります。

于 2013-08-11T11:13:04.967 に答える