多接口继承。从一个铸造到另一个

时间:2009-06-21 09:21:06

标签: c++

考虑以下一组类/接口:

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

现在我有以下课程

void CDiver
{

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

}

我的问题是,“shouldRunAway”可以从fish论证中提取出来是IAggresive还是IFreindly(如果它们中的任何一个......)是否有某种类型的演员可以提供帮助?

5 个答案:

答案 0 :(得分:4)

扩展Drakosha发布的内容,您可以将IFish指针dynamic_cast转换为IAggressive指针并检查它是否为NULL。像这样;

#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;
}

答案 1 :(得分:3)

看看dynamic_cast

答案 2 :(得分:2)

如果您不关心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;
}

答案 3 :(得分:1)

接口定义了所做的类,而不是它是什么。你不应该将它们用作“是一种”关系。在你的情况下,最好在IFish接口中定义一个IsDangerous()方法。

在这种情况下,可以在C ++中进行转换,但这将是糟糕的设计。

答案 4 :(得分:-2)

如果这是Java,你可以这样做:

if( fish instanceof IAggressive )
    runAway();

也许有一些C ++等价?我听过很多关于RTTI的信息......会有帮助吗?

JRH