【问题标题】:Why doesn't my vector recognize my derived classes?为什么我的向量不能识别我的派生类?
【发布时间】:2011-04-25 03:39:28
【问题描述】:

我有一个很大的问题,比我要发布的要大得多,但是如果有人可以帮助我解决这个问题,那么从这里开始就会一帆风顺。

好的,所以我的指针向量拒绝识别它的派生类。让我解释一下。

我有一类 Player 对象,Warrior 和 Wizard 都从这些对象派生而来。 作业要求我将所述对象(战士和巫师)存储到 Player 对象的指针向量中。 这是我目前所拥有的:

vector<Player *> players; 
    cout << "Please enter the number of players" << endl;
    cin >> numOfPlayers;
    total = amountPlaying(numOfPlayers);
for(int i = 0; i < total; i++)
    {
        temp = members();
        if (temp == "Warrior" || temp == "warrior")
            players[i] = new Warrior();
        if (temp == "Wizard" || temp == "wizard")
            players[i] = new Wizard();
        else
        {
            cout << " wrong input, try again " <<endl;
            i--;
        }
        cin >> *players[i];
    }

会员功能:

string members()
{
    string response;
    cout << "Please select a Warrior or Wizard" << endl;
    cin >> response;
    return response;
}

我重载了 Warrior 和 Wizard 以接受通过 cin 的输入,但不是 Player(正如作业所说的那样)。 这是战士的样子(巫师是一样的,但有巫师):

istream& operator>>(istream& in, Warrior& warrior)
{
    int base_strength, base_weapon_level, base_weapon_type;

    cout << "Please enter his/her weapon of choice (1 = sword, 2 = axe, 3 = bow, 4 = knife)" << endl;
    in >> base_weapon_type;
    cout << "Please enter his/her weapon level" << endl;
    in >> base_weapon_level;
    cout << "Please enter strength" << endl;
    in >> base_strength;

    warrior.set_power(base_strength);
    warrior.set_weapon_level(base_weapon_level);
    warrior.set_weapon_type(base_weapon_type);
    return in;
}

现在的问题是,我收到了这个错误(与 cin >>*players[i] 一致):

错误 C2679:二进制“>>”:无运算符 发现它需要一个右手操作数 'Player' 类型的(或者没有 可接受的转换)

现在我该如何解决这个问题?我觉得它不会把它当作战士或巫师,它总是把它当作玩家,但我不想那样!

附:我知道这一切似乎都是多余的,并且与优化相差甚远,但这正是我的教授希望它完成的方式。 :|

任何帮助都将不胜感激,因为我已经为此困扰了几个小时!谢谢谢谢谢谢!

-乔恩

【问题讨论】:

  • 您确定您的教授不想让您将 Player 设为抽象类而将 >> 运算符设为虚拟吗?
  • 我的教授说我只能把operator>>重载在Warrior and Wizard中。这不是抽象的,我这么说的唯一原因是因为我班上的人还没有达到抽象类作为作业的水平。

标签: c++ pointers vector operator-overloading polymorphism


【解决方案1】:

您收到此错误是因为当您在此处取消引用指向 Player 的指针时,您得到的是 Player 对象,而不是 Warrior 或 Wizard:

cin >> *players[i]

如你所说,Player 对象没有operator&gt;&gt;()

可能的解决方案:
1. 在运行时使用dynamic_castPlayer* 转换为Wizard*Warrior*。你可以试试,但还有更方便的方法。示例代码:

Wizard *  pwizard = dynamic_cast <Wizard*>(players[i]);
if (pwizard) {
  // work with pwizard
} 
else {
  Warrior * pwarrior = dynamic_cast <Warrior*>(players[i]);
  if (pwarrior) {
    // work with pwarrior
  }
}

【讨论】:

  • 动态转换可能很讨厌,但它对我来说很有效。感谢您的帮助和大家的帮助!我打算和教授谈谈她为什么不让我们在 Player 类中使用 istream。再次感谢大家。
  • 你的operator&lt;&lt;(应该是operator&gt;&gt;,顺便说一句)不能是成员函数,因此不能是虚拟的。
  • @Marcelo Cantos:是的,我的错,谢谢。考虑到这个主题,我重新编辑了我的答案并阅读了一些关于 stackoverflow 的内容)
  • 你还有operator&lt;&lt;而不是operator&gt;&gt;
【解决方案2】:
cin >> *players[i];

这导致了问题。你有没有将operator&gt;&gt; 重载为:

std::istream & operator>>(std::istream & in, Player &player);

【讨论】:

    【解决方案3】:

    问题是您的operator&gt;&gt; 实际上期望对战士进行操作,但向量包含玩家。

    您可以从派生类沿派生树向上工作,但向下工作并不是一个好主意。你可以做的是为一个通用的 Player 类实现operator&gt;&gt;,然后对它们进行操作,就好像它们是巫师或战士一样。或者,在您的 operator>> 中,您可以调用在两个派生类中都实现的纯多态函数,然后这将为您完成工作。

    希望对你有帮助

    【讨论】:

    • OP 声称家庭作业的条款不允许他为通用 Player 类实现 operator&gt;&gt;
    • Quantum 是对的,由于我的限制,我只能希望像下面的人说的那样尝试动态投射。
    • 回答他的问题,上面就是为什么'向量类不能识别[他的]派生类'。就实际设计而言,这是对他当前算法的简单重新思考-但我确实理解您的意思。
    【解决方案4】:

    您的教授可能禁止了基类operator&gt;&gt;,因为它不起作用。您不能将规范流读取操作设为虚拟,因为第一个参数是流,而不是基类。

    通常的解决方案是这样的:

    class Player {
        ...
        virtual std::istream& read(std::istream& is) = 0;
        ...
    };
    
    std::istream& operator>>(std::istream& is, Player& p) { return p.read(is); }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-11
      • 1970-01-01
      • 2010-10-19
      相关资源
      最近更新 更多