【问题标题】:Static function receives wrong parameters静态函数接收错误的参数
【发布时间】:2015-12-22 10:40:55
【问题描述】:

我在使用静态函数时遇到了这种奇怪的行为,但找不到解决方案。这是来自我正在为学校项目编写的计算机播放器。对于上下文:Board 和 Evaluation 是我的逻辑使用的类,但它们的功能在这里并不重要。

我有一个类 MatchUnit,它有一个创建实例的方法和一个分配本地字段的构造函数:

static void MatchUnit::CreateInstance(Board& realBoard, Board& altBoard, unsigned char turn, char currentPlayer)
{
    // [P2]
    _instance = new MatchUnit(realBoard, altBoard, turn, currentPlayer);
    return _instance;
}

MatchUnit::MatchUnit(Board& realBoard, Board& altBoard, unsigned char turn, char currentPlayer)
{
    _realBoard = &realBoard;
    _altBoard = &altBoard;
    _turn = _moveNr = turn;
    _currentPlayer = currentPlayer;
}

方法在MatchUnit.h中定义的字段

class MatchUnit {
public:
    static MatchUnit* CreateInstance(Board& realBoard, Board& altBoard, unsigned charturn, char currentPlayer);
private:
    Board* _realBoard;
    Board* _altBoard;
    uchar _turn;
    uchar _moveNr;
    char _currentPlayer;
    MatchUnit(Board& realBoard, Board& altBoard, unsigned char turn, char currentPlayer);
};

MatchUnit 是一个单例,但我将实例的 getter 和字段排除在外,因为我认为它们在这里无关紧要。

Board 包含一个非静态私有评估指针 (Evaluation* _eval)

在我的主函数中,我现在调用有问题的方法:

Board* realboard = new Board();
Board* altboard = new Board();

// Internally the board constructors assigned their field pointers:
// _eval = new Evaluation();

// [P1]
MatchUnit::CreateInstance(*realboard, *altboard, 0, currentPlayer);

如果我使用 VS2015 的调试视图并在 [P1] 处暂停,我可以看到板的 _eval 字段没有指向 null。但是当我继续指向 [P2] 时,它们指向的是 null!板子的其他字段也有奇怪的值,之前设置为true的bool是false,整数似乎有随机值,彼此不同!

为什么CreateInstance的参数和我给的完全不一样?

【问题讨论】:

  • 缺少MatchUnit::CreateInstance 定义的返回类型...
  • @Genuigr 好的,让我看看你调用函数 MatchUnit::CreateInstance(*realboard, *altboard, 0, currentPlayer); 后我的问题是否正确在代码中到达 [P2] 时,P1 和 P2 的参数值不同,这应该与您传递的参数相同。
  • @Xtreme_Enigma 是的,你做对了。我更正了返回类型。它什么也不返回,它只是创建一个实例并设置静态 _instance 字段
  • @Genuigr 你能分享点 [p1] 和 [p2] 的结果吗?如果可能的话,函数执行后 _eval 字段的值?如果可以的话,一个可能的 [p3]?
  • 你应该写一个minimal reproducible example

标签: c++ parameters static constants instance


【解决方案1】:

函数CreateInstance 的签名在您的标头和源代码中有所不同。在您的源代码中,您将第三个参数声明为uchar 类型,而在标题中将其声明为unsigned (int)(可能是由于错误输入了空格)。当您调用函数时,编译器会生成与标头中的参数匹配的代码,而您的函数使用源代码中定义的参数。由于参数大小不匹配,您的函数似乎接收到错误的值。您可以通过简单地编辑任一参数定义来解决此问题。

【讨论】:

  • 我更正了,谢谢。在我的程序中,这不是问题,这只是我复制代码的错误。谢谢。
  • 这是一个难以置信的解释。根据平台,参数将通过寄存器(其中其他值不受干扰)或堆栈(堆栈值倾向于保持至少 32 位对齐)中传递。当然,错字可能是未定义的行为,但不太可能引发运行时错误。不过,它非常可能引发编译或链接时错误。
猜你喜欢
  • 2020-12-15
  • 2017-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-01
  • 2012-09-01
  • 2021-07-08
相关资源
最近更新 更多