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
成员的替代方案。