【问题标题】:C++ Class Member Variables Resetting After Loop?C++ 类成员变量在循环后重置?
【发布时间】:2012-02-22 11:02:34
【问题描述】:

在获得this question 的帮助后,我被引导进行更好的调试。在那个过程中,我发现我的问题是这样的:

在 C++ 中工作时,尝试将类的成员变量设置为一个值是可行的,但在循环时却不行。我已将我的代码(要遵循的)简化为我认为最简单的代码,因为它仍然会产生错误。

调用修改变量 pMovXPOS 的 Mover 类的函数,然后可以在同一范围内(在该函数内)和从调用位置(在循环内)检索更新后的变量。但是,在循环时,变量似乎被重置为其原始值。

我在这里发布了整个测试代码。问题在于 Main-test.cpp 文件的 RunWorld() 函数。如果您编译并运行,您应该会看到显示变量更改然后被重置的输出。

这是范围问题吗?建设/破坏问题?指针/引用问题?我不确定从哪里开始(除了更好的调试)。

(由于我是 C++ 新手,我确信我使用的样式和/或方法存在一些明显的问题。如果有任何重大的禁忌,请随时指出。)

提前感谢您的帮助!

//Main-Test.cpp
#include "Globals-Test.h"
#include "Mover-Test.h"

std::vector < Mover > AllMovers;

long SysCounter;

Mover CreateNewMover() {
Mover TempMover;

    TempMover.setXPOS(5);
    TempMover.setYPOS(10);

    return TempMover;

}

void RunWorld() {
Mover TempMover;
unsigned int iMoverLoop;

    srand ( time(NULL) );

    AllMovers.push_back(CreateNewMover());

    for (SysCounter = 0; SysCounter <= 50; SysCounter++) {
        for (iMoverLoop = 0; iMoverLoop < AllMovers.size(); iMoverLoop++) {
            std::cout << "Loop #:" << SysCounter << std::endl;
            TempMover = AllMovers.at(iMoverLoop);
            std::cout << "Is: " << TempMover.getXPOS() << std::endl;
            TempMover.DoMove();             
            std::cout << "Is: " << TempMover.getXPOS() << std::endl;
        }
    }
}



int main() {
    RunWorld();
    return 0;
}

//Globals-Test.h
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <unistd.h>
#include <ctype.h>
#include <math.h>
#include <string>
#include <vector>
#include <time.h>
#include <fstream>

//Mover-Test.h
extern long MoverIndex;

class Mover {

private:

    int pMovXPOS;
    int pMovYPOS;

public:

    int getXPOS();
    void setXPOS(int newXPOS);
    int getYPOS();
    void setYPOS(int newYPOS);

    Mover();
    ~Mover();

    void DoMove();

};

//Mover-Test.cpp
#include "Globals-Test.h"
#include "Mover-Test.h"

Mover::Mover() {    

}

Mover::~Mover() {

}

int Mover::getXPOS() {
    return pMovXPOS;
}

void Mover::setXPOS(int newXPOS) {
    pMovXPOS = newXPOS;
}

int Mover::getYPOS() {
    return pMovYPOS;
}

void Mover::setYPOS(int newYPOS) {
    pMovYPOS = newYPOS;
}

void Mover::DoMove() {
pMovXPOS = pMovXPOS + 1;
pMovYPOS = pMovYPOS + 1;

}

//Compiled with:
g++ -Wall -lm -c Main-Test.cpp
g++ -Wall -lm -c Mover-Test.cpp
g++ -Wall Mover-Test.o Main-Test.o -o world-test.exe -lm

【问题讨论】:

  • 你能做一个minimal的例子来说明问题吗?
  • 是的,分而治之。把它分解成一个最小的例子。你可能会发现它工作正常。然后,您将能够重新添加部件,直到它停止工作并且您可以看到问题所在。
  • 精简版,见上图。还是不行。 :-/
  • @Gaffi 您不应该在堆栈溢出时将 ANSWERED 或类似标签添加到您的标题中。问题列表显示有多少人已回答,如果回答已被接受,数字会变为黄色,因此无需任何其他指示。
  • @Gaffi 通过减少,我的意思是最多大约 15 行代码。

标签: c++ loops member-variables


【解决方案1】:

你的问题是这一行:

TempMover = AllMovers.at(iMoverLoop);

您正在创建位于索引iMoverLoopMover 的副本,然后修改该副本。向量中的对象永远不会被修改,并且在下一次迭代中您的更改将丢失,因为TempMover 将被来自AllMovers 的下一个副本覆盖

解决此问题的一种方法是改用TempMover 的引用。例如:

Mover& tempMover = AllMovers.at(iMoverLoop);
tempMover.DoMove();

【讨论】:

  • +1,虽然 TempMover 在循环中没有超出范围,但它会在每个循环开始时使用向量中元素的值进行重置。
  • @Skizz 啊,是的,为指出这一点而欢呼,在我写答案时并没有过多关注代码。现已修复
  • 真的这么简单吗!?!我曾尝试使用参考指标,但在函数开始时,而不是分配变量的位置,这产生了影响。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2018-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-28
  • 2010-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多