【问题标题】:Create player objects based on the number of players from user input?根据用户输入的玩家数量创建玩家对象?
【发布时间】:2020-12-07 22:30:32
【问题描述】:

背景:
我创建了一个玩家类,我想问用户有多少玩家要玩这个游戏?根据用户输入,我正在尝试创建播放器类的许多实例。但是,我使用以下链接来帮助我:
Create object using user input
http://www.cplusplus.com/forum/beginner/197342/
所以,我尝试了他们的解决方案:

#include "Player.h"

int main() {

    int totalPlayers = -1;
    cout << "Enter total number of players: ";
    while ((totalPlayers < 1) && (totalPlayers > 5)) {
        cout << "How many players will be playing? (1-5): ";
        cin >> totalPlayers;
    }
    vector<Player> players(totalPlayers);

    system("pause");
}    

我收到错误:16LinearChess.exe 中 0x763F40B2 处的未处理异常:Microsoft C++ 异常:内存位置 0x003BF690 处的 std::length_error。
所以,我用谷歌搜索了这个确切的错误并找到了这个链接:Error : std::length_error at memory location
所以,首先他的代码与我的代码无关,但错误是一样的。我不明白答案,但我认为我必须使用堆内存创建实例。所以我试了一下:

#include "Player.h"

int main() {

    int totalPlayers = -1;
    cout << "Enter total number of players: ";
    while ((totalPlayers < 1) && (totalPlayers > 5)) {
        cout << "How many players will be playing? (1-5): ";
        cin >> totalPlayers;
    }
    vector<Player> *players = new Player(totalPlayers);
    delete[] players;

    system("pause");
}    

我收到两个错误:
严重性代码描述项目文件行抑制状态 错误(活动)E0144 类型“玩家 *”的值不能用于初始化类型“std::vector *”的实体 16LinearChess D:\Keshav\Programming Languages\C++\Beginner\ 01 Michael Dawson\16LinearChess\LinearChess.cpp 64


严重性代码描述项目文件行抑制状态 错误(活动)E0289 构造函数“Player::Player”的实例与参数列表不匹配 16LinearChess D:\Keshav\Programming Languages\C++\Beginner\01 Michael Dawson\16LinearChess\LinearChess.cpp

这是我的 Player 类:

#include <iostream>

class Player : public Board {
protected:
    int m_position;
    Log logger;
    int m_playerNumber;
public: 
    static int m_numberOfPlayers;
    Player() :m_position(0) {
        ++m_numberOfPlayers; 
        m_playerNumber = m_numberOfPlayers;
    }

    void m_SetPlayerPosition(int &position) {
        if ((position < 0) || (position > 100)) {
            m_position = 0;
            logger.Error("Position cannot be less than or greater than 100. Your position has been reset to 0 because you fell out of the map.");
        }
        else {
            m_position = position;
        }
        m_SetBoardPosition(m_position, m_numberOfPlayers); // update the position on the board.
    }

    friend ostream &operator << (ostream &os, Player &player) {
        os << "Player position on board: " << player.m_position << "\nPlayer Number: " << player.m_playerNumber << '\n';
        return os;
    }
};

int Player::m_numberOfPlayers = 0; // initializing total number of players.

谢谢!

【问题讨论】:

标签: c++ oop vector


【解决方案1】:

问题在于您的 while 循环:

    int totalPlayers = -1;
    cout << "Enter total number of players: ";
    while ((totalPlayers < 1) && (totalPlayers > 5)) {
        cout << "How many players will be playing? (1-5): ";
        cin >> totalPlayers;
    }

while 循环只会在条件为真时运行,但条件永远不会为真,因为没有数字可以小于 1,也不能大于 5。由于条件不为真,while 循环永远不会运行,totalPlayers 将等于 -1,如果您尝试访问数组索引,这是您永远不会想要的。

将其更改为:totalPlayers &lt; 1 || totalPlayers &gt; 5 改为 ||,您应该没问题。

对于错误:

Unhandled exception at 0x763F40B2 in 16LinearChess.exe: Microsoft C++ exception: std::length_error at memory location 0x003BF690.

您的代码引发了异常,因为 totalPlayers 等于 -1。所以你基本上是这样做的:

vector<Player> players(-1);

这是没有意义的,因为您正在创建一个包含 -1 元素的数组?所以代码抛出了一个异常,告诉你出了点问题。 std::length_error 应该给出错误提示。

正如许多 cmets 所说,不要这样做:

vector<Player> *players = new Player(totalPlayers);

vector 的全部目的是让您不要那样做。您的第一个示例运行良好:

vector<Player> players(totalPlayers);

【讨论】:

  • 好吧,如果 -1 环绕到最大的 unsigned int 值,为什么它不会创建那么多实例呢?为了防止一些内存问题?
  • 它没有。您将 -1 存储到 int 变量中。 int 变量可以存储负数。另一方面,如果您将其存储在unsigned int...
  • @user4581301:但你有不同的贡献,老实说,好先生更有价值。
  • 或者如果你在谈论将它传递给向量,那么它不会创建太多实例,因为向量只能容纳这么多元素
  • 或更具体地说,它用于表示 unsigned int、unsigned long、unsigned short 等。它在 std::vector.size() 等通用无符号类型为用过的。这有点难以解释,但您可以尝试在此处阅读更多内容:stackoverflow.com/questions/19732319/…
【解决方案2】:

如果std::vector 尝试将大小调整为大于max_size() 的大小,则会出现std::length_error。大多数情况下,这是由错误的输入引起的——例如-1,它将被转换为std::vector&lt;T&gt;::size_type 的最大unsigned 值。


从你分享的代码来看,问题实际上是由于你的while循环条件:

    while ((totalPlayers < 1) && (totalPlayers > 5))

totalPlayers 不可能同时小于1 大于5——所以永远不会进入这个循环。由于您分配给totalPlayers 的默认值是-1,因此您调整大小的大小会溢出并成为最大的unsigned 值——这会触发std::length_error

解决此问题应该可以解决您的错误。

【讨论】:

  • 哦,我从来不知道它会环绕到最大的无符号值。可是等等!如果是这样,那么它不应该创建实例吗?它不应该创建尽可能多的实例吗?
  • 如果请求的大小大于std::vector&lt;T&gt;::max_size(),则会引发std::length_error 异常。由于-1 转换为设置了所有位的无符号值,因此在32 位系统上,这将是多个2^32-1 实例(4,294,967,295 个实例)——这很可能大于max_size()。这将解释为什么抛出异常而不是调整大小
  • 啊,所以他们在那里实施了安全功能!或者,由于一个实例的大小,您根本无法创建那么多实例,因为它有其数据成员,并且可能导致内存泄漏,对吧?
  • 不是内存泄漏,而是一个粗略的衡量标准,即“没有人”有足够的内存来分配那么大的数组。泄漏是当你请求一个资源(文件、内存块、一匹马)时,你得到了它,(在你的失败案例中没有发生)并且你完成后没有把它收起来,所以没有人可以找到如果他们再次需要它。就像你哥哥不把螺丝刀放回去一样。你要么必须买一把新螺丝刀,要么放弃需要螺丝刀的工作。
  • 请注意,您通常可以请求比实际拥有的更多的存储空间。大多数现代操作系统将允许您拥有内存,但在您实际使用它之前不会将其提供给您。即便如此,它们也可能只给你刚刚使用的一点点。有可能成功获得 Zounds... 大数组,然后在操作系统无法提供承诺的内存时崩溃。与此同时,当内存用完时,it could start using anything else it can use for storage, like the hard drive.
猜你喜欢
  • 2019-01-14
  • 1970-01-01
  • 2019-09-17
  • 2015-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多