3 Stimmen

Vererbung mehrerer Schnittstellen. Casting von einer zur anderen

Betrachten Sie die folgende Gruppe von Klassen/Schnittstellen:

class IFish{
public:
virtual void eat() = 0;
}

class IFriendly{
public:
virtual void protect() = 0;
}

class IAggresive{
public:
virtual void attack(Point inDest) = 0;
}

class CDolphin : public IFish, IFriendly{
eat...
protect....
}

class CShark : public IFish, IAggresive{
eat....
attack...
}

Jetzt habe ich die folgende Klasse

void CDiver
{

Void shouldRunAway(IFish* fish)
{
//???
}

}

Meine Frage ist, kann "shouldRunAway" aus dem Fisch-Argument extrahieren, ob es ein IAggresive oder IFreindly ist (wenn es überhaupt einer von diesen ist...) gibt es eine Art von Casting, die helfen kann?

5voto

xian Punkte 4537

Erweiternd auf, was Drakosha gepostet, würden Sie dynamic_cast der IFish Zeiger in eine IAggressive Zeiger und prüfen, ob es NULL oder nicht ist. Etwa so;

#include <iostream>

class IFish {
public:
    virtual void eat() = 0;
};

class IFriendly {
public:
    virtual void protect() = 0;
};

class IAggressive {
public:
    virtual void attack() = 0;
};

class Dolphin : public IFish, public IFriendly {
public:
    virtual void eat() {
        std::cout << "Dolphin::eat()\n";
    }

    virtual void protect() {
        std::cout << "Dolphin::protect()\n";
    }
};

class Shark : public IFish, public IAggressive {
public:
    virtual void eat() {
        std::cout << "Shark::eat()\n";
    }

    virtual void attack() {
        std::cout << "Shark::attack()\n";
    }
};

class Diver {
public:
    void shouldRunAway( IFish *fish ) {
        if ( dynamic_cast<IAggressive *>( fish ) != NULL ) {
            std::cout << "Run away!\n";
        } else {
            std::cout << "Don't run away.\n";
        }
    }
};

int main( int argc, char *argv[] ) {
    Dolphin dolphin;
    Shark shark;
    Diver diver;

    diver.shouldRunAway( &dolphin );
    diver.shouldRunAway( &shark );

    return 0;
}

3voto

Drakosha Punkte 11577

Werfen Sie einen Blick auf dynamisch_gecastet .

2voto

Rimo Punkte 447

Sie können das Visitor-Muster verwenden, wenn Sie sich nicht um dynamic_cast kümmern

#include <iostream>

class Diver;

class IFish {
public:
    virtual void eat() = 0;
    virtual void visit(Diver*) = 0;
};

class IFriendly {
public:
    virtual void protect() = 0;
};

class IAggressive {
public:
    virtual void attack() = 0;
};

class Diver {
public:
    void shouldRunAway( IFish *fish ) {
        fish->visit(this);
    }

    void runAway()
    {
        std::cout << "Run away!\n";
    }

    void dontRunAway()
    {
        std::cout << "Don't run away!\n";
    }
};

class Dolphin : public IFish, public IFriendly {
public:
    virtual void eat() {
        std::cout << "Dolphin::eat()\n";
    }

    virtual void protect() {
        std::cout << "Dolphin::protect()\n";
    }

    virtual void visit(Diver* diver)
    {
        diver->dontRunAway();
    }
};

class Shark : public IFish, public IAggressive {
public:
    virtual void eat() {
        std::cout << "Shark::eat()\n";
    }

    virtual void attack() {
        std::cout << "Shark::attack()\n";
    }

    virtual void visit(Diver* diver)
    {
        diver->runAway();
    }
};

int main( int argc, char *argv[] ) {
    Dolphin dolphin;
    Shark shark;
    Diver diver;

    diver.shouldRunAway( &dolphin );
    diver.shouldRunAway( &shark );

    return 0;
}

1voto

Dani van der Meer Punkte 6069

Die Schnittstellen definieren, was eine Klasse fait und nicht was es ist . Sie sollten sie nicht als "Ist ein"-Beziehung verwenden. In Ihrem Fall wäre es besser, eine IsDangerous()-Methode in der IFish-Schnittstelle zu definieren.

Casting ist in diesem Fall in C++ möglich, aber es wäre ein schlechtes Design.

-2voto

jrharshath Punkte 24857

Wenn dies Java wäre, könnten Sie das tun:

if( fish instanceof IAggressive )
    runAway();

Vielleicht gibt es eine Entsprechung in C++? Ich habe schon viel über RTTI gehört. Wird das helfen?

jrh

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X