【问题标题】:C++ Can't Access Private Class Variables Even from a Same Class Function即使来自同一个类函数,C++ 也无法访问私有类变量
【发布时间】:2014-03-21 23:52:05
【问题描述】:

所以我正在开发一个二十一点游戏的程序。对于游戏中的每个玩家,我都有一个名为 Player 的类。问题在于Player.cpp中的这段代码:

void Player::SetFunds(int amt){
  cout << "setting funds:" << endl;
  cout << m_funds << "m_funds" << endl;
  m_funds = amt;
  cout << "done" << endl;
}

编译时出现分段错误。 “设置资金:”行打印,但我无法打印 m_funds,也无法将其设置为 amt(我在为 m_funds 添加打印语句之前尝试过)。

这是 Player.h 中函数的声明(包含在 Player.cpp 中)。

void SetFunds(int amt);

这是我在 Player 类中拥有 m_funds 以及其他私有变量的地方。

 private:
  char* m_name;
  int m_funds;
  int m_bet;
  Hand m_hand;
  bool m_busted;
};

我有什么遗漏吗?为什么即使我在 Player 类函数中,我似乎也无法访问私有 Player 类变量?即使在“设置资金”打印后立即出现分段错误,错误是否可能在其他地方?

另外,我可以修改构造函数中的私有变量就好了,如下:

Player::Player(char *name, int amt){
  m_name = name;
  cout << amt << endl; //Amount prints as 100
  m_funds = amt; // sets m_funds to 100
  cout << m_funds << endl; //m_funds prints as 100 just fine
  m_bet = 0;
  m_hand = Hand();
  m_busted = false;
}

编辑: 这是我在 Blackjack.cpp 中调用函数 SetFunds 的地方: (m_players 是 Players 的向量,作为 Blackjack 类的私有变量。)同样,amt couts 为 100。

void Blackjack::SetPlayerFunds(int player, int amt){
  cout << amt << endl;
  m_players[player].SetFunds(amt);
}

这里是我从 Project.cpp(包含 main)调用该函数的地方: (注意:这是一个项目,我不能编辑这个文件,我的代码必须围绕它)

Blackjack *CreateGame(int argc, char *argv[]) {
  char **names;
  int *funds;
  int numPlayers;
  Blackjack *game;

  numPlayers = ProcessArgs(argc - 1, &argv[1], names, funds);

  game = new Blackjack(names, numPlayers);
  for (int p = 0; p < numPlayers; p++) {
    game->SetPlayerFunds(p, funds[p]);
}

编辑 2: 这是 Blackjack::CreateGame 内部调用的 Blackjack 类构造函数。

Blackjack::Blackjack(char *names[], int numPlayers){
  std::vector<Player> m_players;
  m_dealer = Player();

  int amt = 100;

  for(int i = 0; i < numPlayers; i++){
    Player player(names[i], amt);
    m_players.push_back(player);
  }
}

【问题讨论】:

  • 使用调试器。 this 指针可能为空,即您正在对无效对象调用成员函数。
  • 调试器?有什么程序或我可以使用的东西吗?还有,this指针是什么?
  • 如果您使用cout &lt;&lt; m_bet 而不是m_funds,会发生什么?但只是为了确保您可以在构造函数中临时设置 m_bet = 1 而不是 0
  • 我做到了,我也无法计算出 m_bet。所以它似乎是我无法访问的所有私有变量。
  • “分段错误”与“无法访问”完全不同。如果您无法访问变量,编译器会在您运行程序之前给出错误。

标签: c++ class private


【解决方案1】:

您的问题出在 Blackjack 构造函数中。

Blackjack::Blackjack(char *names[], int numPlayers){
  std::vector<Player> m_players;
  m_dealer = Player();

  int amt = 100;

  for(int i = 0; i < numPlayers; i++){
    Player player(names[i], amt);
    m_players.push_back(player);
  }
}

您正在构造函数中的堆上创建 m_player,分配和添加玩家,但可能永远不会初始化类中同名的真实成员...

要解决这个问题,请移除 std::vector m_players;

【讨论】:

    【解决方案2】:

    嗯,看来this指针很奇怪..

    我建议这个测试代码。

    void Blackjack::SetPlayerFunds(int player, int amt)
    {
      cout << amt << endl;
    
      // if "m_players" is std::vector
      m_players.at(player).SetFunds(amt);
      // elif "m_players" is C-array
      if (player >= sizeof(m_players)/sizeof(m_players[0]))
        abort(); // assert(false) or setting breakpoint will be better, if you can use debugger
      m_players[player].SetFunds(amt);
    }
    

    【讨论】:

    • 好吧,我把它改成了你的“m_players.at(player).SetFunds(amt);”因为我使用的是标准:向量。你是对的,它修复了this。但是现在我得到了一个不同的错误:在抛出 'std::out_of_range' what(): vector::_M_range_check Abort 的实例后调用终止
    • @seekerlite 是的,这正是我所说的。 at() 抛出std::out_of_range 如果player &gt;= m_players.size()。如果您不能使用任何调试器,我建议将try { m_players.at(player).SetFunds(amt); } catch (std::out_of_range&amp;) { std::cerr &lt;&lt; "bug:" player &lt;&lt; std::endl; } 插入SetPlayerFunds。如果你可以使用调试器,你的调试器可能会在抛出未捕获的异常时通知你
    猜你喜欢
    • 2012-01-04
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 2014-09-05
    • 2015-09-25
    相关资源
    最近更新 更多