【问题标题】:How do I pass an enum by reference in this simple example?在这个简单的示例中,如何通过引用传递枚举?
【发布时间】:2014-03-06 22:54:33
【问题描述】:

我的代码有问题,我写了这个简单的例子来说明它。

我有一个具有公共枚举 PlayerType 的 Player 类。我有一个带有 createPlayer 方法的 Manager 类,该方法接受对播放器和播放器类型的引用。

但是我不能让它编译——注意,我不能改变 createPlayer 方法的签名,每个参数必须是一个对象引用。

我做错了什么?

播放器.h

#ifndef PLAYER_H
#define PLAYER_H

using namespace std;

class Player {
  public:
    Player();
    enum PlayerType { FORWARD, DEFENSEMAN, GOALIE };
    void setType(PlayerType);
  private:
    PlayerType type;
};

#endif

播放器.cc

#include <iostream>

using namespace std;

#include "Player.h"

Player::Player() {
}

void Player::setType(PlayerType type) {
  this->type = type;
}

经理.h

#ifndef MANAGER_H
#define MANAGER_H

using namespace std;

#include "Player.h"

class Manager {
  public:
    void createPlayer(Player& player, PlayerType& playerType);
};

#endif

经理.cc

#include <iostream>

using namespace std;

#include "Player.h"

#include "Manager.h"

void Manager::createPlayer(Player& player, PlayerType& playerType) {
  cout << "inside Manager::createPlayer" << endl;
}

Main.cc

#include <iostream>

using namespace std;

#include "Player.h"
#include "Manager.h"

int main() {

  Manager manager;
  Player player;
  manager.createPlayer(player, Player::FORWARD);

  return 0;
}

当我编译 gcc -o a.out *.cc *.h 时出现此错误:

In file included from Main.cc:6:0:
Manager.h:10:39: error: ‘PlayerType’ has not been declared
Main.cc: In function ‘int main()’:
Main.cc:12:47: error: no matching function for call to ‘Manager::createPlayer(Player&, Player::PlayerType)’
Main.cc:12:47: note: candidate is:
Manager.h:10:10: note: void Manager::createPlayer(Player&, int&)
Manager.h:10:10: note:   no known conversion for argument 2 from ‘Player::PlayerType’ to ‘int&’
In file included from Manager.cc:7:0:
Manager.h:10:39: error: ‘PlayerType’ has not been declared
Manager.cc:9:44: error: ‘PlayerType’ has not been declared
Manager.h:10:39: error: ‘PlayerType’ has not been declared

我该怎么做才能完成这项工作?

【问题讨论】:

  • 您的 manager.cc 代码错误。
  • @RichardPennington Thx,代码现已修复。有什么想法吗?
  • 问题是枚举是一个常量,而不是一个对象。我认为您有充分的理由不更改签名? (作业?)你将如何创建可以通过引用传递的具有你想要的枚举值的东西?
  • @RichardPennington 是的,我不能更改签名的原因是因为方法是教授那样提供的。然而,这个问题说明了我在一项更大的任务中遇到的一个问题——我正在寻求一个障碍的帮助,而不是试图让其他人为我做作业。谢谢。
  • 我并不想批评。查看下面 Etienne 的答案,了解一种解决方法。这就是我所说的创建可以作为参考传递的东西的意思。

标签: c++ enums


【解决方案1】:

为了能够使用引用,您需要将值存储到变量中。

int main() {

  Manager manager;
  Player player;
  Player::PlayerType t = Player::FORWARD;
  manager.createPlayer(player,t);

  return 0;
}

【讨论】:

  • 就是这样!快速跟进问题,为了使它工作,我必须将 createPlayer 中的参数更改为 Player::PlayerType&amp; - 我怎样才能使其仅与 PlayerType&amp; 一起工作?
  • 您可以将 PlayerType 枚举声明移到 Player 之外。
  • 你可以将枚举定义移出 Player 类
  • 我尝试将“enum”行移到“class Player {”上方,并将所有 Player::PlayerType 更改为“PlayerType”。但在 Main.cc 中,'PlayerType t = PlayerType::FORWARD' 行给出了编译器错误:“'PlayerType' 不是类或命名空间”——有什么想法吗?
  • 编译器是对的,PlayerType 不是类或命名空间。如果您没有限定名称怎么办?
【解决方案2】:

你需要改变

void createPlayer(Player&amp; player, Player::PlayerType&amp; playerType);

void createPlayer(Player&amp; player, const Player::PlayerType&amp; playerType);

将 Player::FORWARD 作为参数传递会创建一个临时 PlayerType 值,该值只能作为 const 引用或按值传递。

【讨论】:

  • 不幸的是他无法改变它。
  • 谢谢格里特。理查德是对的,我不能更改签名。看起来我对艾蒂安的回答已经完成了一半。有人知道我给艾蒂安的后续问题的答案吗?
【解决方案3】:

问题是在这个调用中

manager.createPlayer(player, Player::FORWARD);

第二个参数是一个临时对象,你不能将非 const 引用绑定到一个临时对象。

所以你应该将函数声明为

void Manager::createPlayer(Player& player, const Player::PlayerType& playerType)

虽然我不认为使用参考有很大的意义。我会更简单地声明函数

void Manager::createPlayer(Player& player, Player::PlayerType playerType)

没有参考。

【讨论】:

  • 谢谢,但我无法更改签名。
猜你喜欢
  • 1970-01-01
  • 2019-01-28
  • 1970-01-01
  • 1970-01-01
  • 2011-04-29
  • 2012-07-11
  • 2021-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多