Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 处理不同派生类对象之间的交互_C++_Inheritance_Downcast_Mediator - Fatal编程技术网

C++ 处理不同派生类对象之间的交互

C++ 处理不同派生类对象之间的交互,c++,inheritance,downcast,mediator,C++,Inheritance,Downcast,Mediator,我有一个程序,其中我有一个指向基类的指针向量,在那里我存储了多个不同派生类的实例。所有这些对象根据其类型以不同的方式相互交互,我希望以智能的方式实现这些交互。我更喜欢有一个中介类,在那里保存尽可能多的与这些交互相关的代码 以下是我想要实现的目标的简化版本: #include <iostream> #include <vector> class Gesture {}; class Rock : public Gesture {}; class Paper : publ

我有一个程序,其中我有一个指向基类的指针向量,在那里我存储了多个不同派生类的实例。所有这些对象根据其类型以不同的方式相互交互,我希望以智能的方式实现这些交互。我更喜欢有一个中介类,在那里保存尽可能多的与这些交互相关的代码

以下是我想要实现的目标的简化版本:

#include <iostream>
#include <vector>

class Gesture {};

class Rock : public Gesture {};

class Paper : public Gesture {};

class Scissors : public Gesture {};

class Game {
    public:
        static void play(Rock* first, Rock* second) {
            std::cout << "Rock ties with rock." << std::endl;
        }
        static void play(Rock* first, Paper* second) {
            std::cout << "Rock is beaten by paper." << std::endl;
        }
        static void play(Rock* first, Scissors* second) {
            std::cout << "Rock beats scissors." << std::endl;
        }
        static void play(Paper* first, Rock* second) {
            std::cout << "Paper beats rock." << std::endl;
        }
        static void play(Paper* first, Paper* second) {
            std::cout << "Paper ties with paper." << std::endl;
        }
        static void play(Paper* first, Scissors* second) {
            std::cout << "Paper is beaten by scissors." << std::endl;
        }
        static void play(Scissors* first, Rock* second) {
            std::cout << "Scissors are beaten by rock." << std::endl;
        }
        static void play(Scissors* first, Paper* second) {
            std::cout << "Scissors beat paper." << std::endl;
        }
        static void play(Scissors* first, Scissors* second) {
            std::cout << "Scissors tie with scissors." << std::endl;
        }
};

int main()
{   
    Rock rock;
    Paper paper;
    Scissors scissors;
    
    std::vector<Gesture*> gestures;
    gestures.push_back(&rock);
    gestures.push_back(&paper);
    gestures.push_back(&scissors);
    
    for(int i = 0; i < 3; ++i) {
        for(int j = 0; j < 3; ++j) {
            // alas, downcasting doesn't happen automagically...
            Game::play(gestures[i], gestures[j]);
        }
    }

    return 0;
}

#包括
#包括
类手势{};
摇滚类:公共手势{};
课堂论文:公共手势{};
类剪刀:公共手势{};
班级游戏{
公众:
静态无效播放(摇滚乐*第一,摇滚乐*第二){

std::cout我对这种情况的典型反应是向
enum
类型的基类添加一个字段

typedef enum {rockType,paperType,scissorsType} fred;

class Gesture
{
    virtual fred Type() = 0;
}

class Rock : public Gesture
{
    fred Type() { return typeRock;}
}

然后你可以调用每个对象的
Type()
函数并使用
switch
语句分派每个对象。

由于我似乎无法避免使用丑陋的
switch
语句或一系列
if
-
else if
语句,我想我只需要做如下操作,不需要将
enum
引入类或对它们进行其他修改伊瑟

#include <iostream>
#include <vector>

class Gesture {
    virtual void foo() {}
};

class Rock : public Gesture {
    virtual void foo() {}
};

class Paper : public Gesture {
    virtual void foo() {}
};

class Scissors : public Gesture {
    virtual void foo() {}
};

class Game
{
    public:
        static void rock_vs_rock() {
            std::cout << "Rock ties with rock." << std::endl;
        }
        static void rock_vs_paper() {
            std::cout << "Rock is beaten by paper." << std::endl;
        }
        static void rock_vs_scissors() {
            std::cout << "Rock beats scissors." << std::endl;
        }
        static void paper_vs_rock() {
            std::cout << "Paper beats rock." << std::endl;
        }
        static void paper_vs_paper() {
            std::cout << "Paper ties with paper." << std::endl;
        }
        static void paper_vs_scissors() {
            std::cout << "Paper is beaten by scissors." << std::endl;
        }
        static void scissors_vs_rock() {
            std::cout << "Scissors are beaten by rock." << std::endl;
        }
        static void scissors_vs_paper() {
            std::cout << "Scissors beat paper." << std::endl;
        }
        static void scissors_vs_scissors() {
            std::cout << "Scissors tie with scissors." << std::endl;
        }
        static void play(Gesture* first, Gesture* second)
        {
            // I've never really liked switch statements...
            if(dynamic_cast<Rock*>(first) && dynamic_cast<Rock*>(second))
            {
                rock_vs_rock();
            }
            else if(dynamic_cast<Rock*>(first) && dynamic_cast<Paper*>(second))
            {
                rock_vs_paper();
            }
            else if(dynamic_cast<Rock*>(first) && dynamic_cast<Scissors*>(second))
            {
                rock_vs_scissors();
            }
            else if(dynamic_cast<Paper*>(first) && dynamic_cast<Rock*>(second))
            {
                rock_vs_rock();
            }
            else if(dynamic_cast<Paper*>(first) && dynamic_cast<Paper*>(second))
            {
                paper_vs_paper();
            }
            else if(dynamic_cast<Paper*>(first) && dynamic_cast<Scissors*>(second))
            {
                paper_vs_scissors();
            }
            else if(dynamic_cast<Scissors*>(first) && dynamic_cast<Rock*>(second))
            {
                scissors_vs_rock();
            }
            else if(dynamic_cast<Scissors*>(first) && dynamic_cast<Paper*>(second))
            {
                scissors_vs_paper();
            }
            else if(dynamic_cast<Scissors*>(first) && dynamic_cast<Scissors*>(second))
            {
                scissors_vs_scissors();
            }
        }
};

int main()
{   
    Rock rock;
    Paper paper;
    Scissors scissors;
    
    std::vector<Gesture*> gestures;
    gestures.push_back(&rock);
    gestures.push_back(&paper);
    gestures.push_back(&scissors);
    
    for(int i = 0; i < gestures.size(); ++i)
    {
        for(int j = 0; j < gestures.size(); ++j)
        {
            Game::play(gestures[i], gestures[j]);
        }
    }

    return 0;
}
#包括
#包括
课堂手势{
虚拟void foo(){}
};
摇滚类:公众姿态{
虚拟void foo(){}
};
课堂论文:公众姿态{
虚拟void foo(){}
};
课堂剪子:公众手势{
虚拟void foo(){}
};
班级游戏
{
公众:
静态孔隙岩石与岩石(){

std::cout你的意思是
fred Type(){return typeRock;}
Hmm,在类中引入
enum
s不是太有侵略性-这很好。但是我不喜欢嵌套
switch
语句的想法。实际上,我目前有五个不同的派生类(不,另外两个不是“Lizard”和“Spock”)这将导致一个相当长的
switch
语句。因此,虽然这是对我的计划C的改进,但我仍然会选择计划B().不管怎样,我要么没有阅读或充分考虑链接背后的描述-它不能完全解决我的问题。编辑:我的意思是我仍然需要一个
开关
语句或其他东西。当然,如果这是一个性能关键部分,那么检查
枚举
肯定比
动态\u cast
要快得多。一个也可以使用
std::vector signities
作为
enum
成员的替代方案。