0

私がやろうとしていることは、次のようなものです。

void SomeFunction(Base *){//do something}
void SomeFunction(Derived *){//do something else}

これは C++ で可能ですか? これまでの私の試みは、関数の基本バージョンを呼び出すだけです。わかりやすくするための例を次に示します。

例:

#include <iostream>
#include <vector>

class Base
{
    public:
        Base () {std::cout << "Base Constructor for " << this << std::endl;}
        void virtual PrintSomething ()
        {
            std::cout << "I am Base!" << std::endl;
        };
};

class Derived : public Base
{
    public:
        Derived () : Base () {std::cout << "Derived Construtor for " << this << std::endl;}
        void virtual PrintSomething ()
        {
            std::cout << "I am Derived!" << std::endl;
        };
};

void DoAmazingStuff ( Base * ) {std::cout << "Amazing!" << std::endl;}
void DoAmazingStuff ( Derived * ) {std::cout << "DERP!" << std::endl;}

int main ()
{
    std::vector<Base *> some_vector;

    Base *x = new Base ();
    Derived *y = new Derived ();

    some_vector.push_back ( x );
    some_vector.push_back ( y );

// This is the part that isn't functioning as expected.
/******************************************/
    DoAmazingStuff ( some_vector[0] );
    DoAmazingStuff ( some_vector[1] );
/******************************************/

    std::cin.get ();
    std::cin.get ();
    delete some_vector[0];
    delete some_vector[1];
}

次の行は呼び出されません。

void DoAmazingStuff ( Derived * ) {std::cout << "DERP!" << std::endl;}
4

1 に答える 1

7

確かに可能です。ただし、Derivedバージョンは、ポインターの静的型が の場合にのみ呼び出されますDerived*。例えば:

Base * b = new Base;        // static and dynamic types are Base
Derived * d = new Derived;  // static and dynamic types are Derived
Base * bd = new Derived;    // static type Base, dynamic type Derived

SomeFunction(b);   // Base overload
SomeFunction(d);   // Derived overload
SomeFunction(bd);  // Base overload (from static type)

動的ディスパッチ (動的型に基づいて関数を選択する) は、オーバーロードされた非メンバー関数ではなく、仮想メンバー関数を呼び出すときにのみ発生します。

struct Base {
    virtual void SomeFunction() {/*do something*/}
};
struct Derived : Base {
    virtual void SomeFunction() {/*do something else*/}
};

b->SomeFunction();  // Base version
d->SomeFunction();  // Derived override
bd->SomeFunction(); // Derived override (from dynamic type)

メンバー関数の助けを借りて、非メンバー関数で動的ディスパッチのようなものを実現できます。

void SomeFunction(Base * b) {b->SomeFunction();}

コメントに記載されているように、この手法を拡張して複数のディスパッチを実装し、複数の関数引数の動的な型に基づいて関数を選択できます。しかし、それは質問の範囲を超えています。

于 2013-05-31T12:08:51.000 に答える