The ambiguity of interfaces. Casting from one to another

Consider the following set of classes / Interfaces:

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...
}

Now i have the next class

void CDiver
{

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

}

My question is: can "mustRunAway" extract from the fish argument, is it IAggresive or IFreindly (if at all any of this ...) is there some kind of drop that might help?

+3
source share
5 answers

Turning around what Drakosha sent, you would point the IFish pointer to the IFish pointer to the IAggressive pointer and check if it is NULL or not. Like this:

#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;
}
+4
source

Take a look at dynamic_cast .

+3
source

, , , . "". IsDangerous() IFish.

Casting in this case is possible in C ++, but it will be a bad design.

+1
source

You can use the visitor template if you do not like dynamic_cast

#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;
}
+1
source

if it was Java, you can do:

if( fish instanceof IAggressive )
    runAway();

Perhaps there is some C ++ equivalent? I heard a lot about RTTI .. will it help?

Jrh

-2
source

Source: https://habr.com/ru/post/1710939/


All Articles