我正在为Xbox 360编写一个开源项目,这是我第一次使用C ++而且我显然做了一些事情(很可能是很多事情)。
我目前的具体问题是我创建了一个类的许多实例,传入对构造函数中对象的引用,并将成员变量设置为该对象。
稍后,当我访问这些对象时,成员变量不包含我在构造函数中赋给它的对象。
此外,这些对象有一个Update(float x,float y)方法,在这个方法中我只是将x和y分配给成员变量_x和_y。
当我稍后访问这些值时,它们就是垃圾。
我将尝试在此处发布相关代码,但可能会有一些我想念的内容,所以以下是github项目Github - Xenu的链接。
我所指的类是source / GUIApplicationPanel,它们的实例化/使用在source / GUIManager中。
这是我实例化许多实例的对象:
GUIApplicationPanel.H
class GUIApplicationPanel {
public:
GUIApplicationPanel(LibXenonApplication libXenonApplication);
void update(float x, float y);
void draw();
private:
LibXenonApplication application;
float _x, _y;
};
GUIApplicationPanel.CPP
GUIApplicationPanel::GUIApplicationPanel(LibXenonApplication libXenonApplication)
{
application = libXenonApplication;
}
void GUIApplicationPanel::update(float x, float y)
{
_x = x;
_y = y;
}
void GUIApplicationPanel::draw()
{
Draw::DrawColoredRect(_x, _y, 0.3f, 0.3f, ThemeManager::GetPanelColor());
}
以下是创建它们的代码:
GUIManager.H
class GUIManager {
public:
void update(controller_data_s controller);
void draw();
private:
/* SNIP SNIP */
vector<GUIApplicationPanel> *currentPanels;
vector<GUIApplicationPanel> applicationPanels;
};
GUIManager.C
vector<LibXenonApplication> applications = LibXenonApplicationManager::GetApplications(applicationsPath);
// Create panels for applications
for(vector<LibXenonApplication>::iterator iter = applications.begin(); iter != applications.end(); ++iter) {
applicationPanels.push_back(GUIApplicationPanel(*iter));
}
以下是更新它们的代码:
currentPanels = &applicationPanels;
// Render each screens worth of panels
for(int currentPass = 0; currentPass < renderPasses; currentPass++) {
horizontalOffset = currentPass * 1.0f;
for(int verticalPanel = 0; verticalPanel < verticalPanels; verticalPanel++) {
for(int horizontalPanel = 0; horizontalPanel < horizontalPanels; horizontalPanel++) {
// Make sure we haven't exceeded the amount of panels we're drawing...
if(panelIndex >= currentPanels->size()){break;}
// Get the panel at the current index
GUIApplicationPanel currentPanel = currentPanels->at(panelIndex);
// Calculate its position
float panelX = horizontalOffset + xStart + (horizontalPanel * panelWidth) + (horizontalPanel * panelGap);
float panelY = yStart + (verticalPanel * panelHeight) + (verticalPanel * panelGap);
// Update the panel
currentPanel.update(panelX, panelY);
// Move to the next panel...
panelIndex++;
}
}
}
最后这里是访问它们的值的代码:
for(vector<GUIApplicationPanel>::iterator iter = currentPanels->begin(); iter != currentPanels->end(); ++iter) {
iter->draw();
}
说实话,我完全没有想法 - 在构造函数以外的任何地方访问应用程序变量会导致它变成垃圾,同样使用_x和_y(除了在update方法中)。
我进行了一些登录,因此将在面板的更新方法中记录一行,在设置后记录_x和_y的值,并显示应用程序的名称(其中显示为空白)在日志中。)
调用draw方法时还会记录一行,显示_x,_y和application的当前值:
Updating to x -0.70 y 0.40
Updating to x -0.30 y 0.40
Updating to x 0.10 y 0.40
Updating to x 0.50 y 0.40
Updating to x 0.90 y 0.40
Updating to x -0.70 y 0.80
Updating to x -0.30 y 0.80
Updating to x 0.10 y 0.80
Updating to x 0.50 y 0.80
Drawing at x 0.00 y 0.00
Drawing at x 0.00 y 0.00
Drawing at x 0.00 y 0.00
Drawing at x 0.00 y 0.00
Drawing at x 0.00 y 0.00
Drawing at x 0.00 y 0.00
Drawing at x 0.00 y 0.00
Drawing at x 0.00 y 275577729171396449271808.00
Drawing at x 0.00 y 0.00
答案 0 :(得分:2)
问题在于您访问向量中元素的方式:
GUIApplicationPanel currentPanel = currentPanels->at(panelIndex);
这将获取元素的副本,因此您可以设置副本的属性,而不是容器中保存的项目。获取参考,然后您可以修改容器中的项目..
编辑:基于评论,因为您已经意识到std::vector<>::at()
会返回引用,所以您需要做的是将上述内容更改为引用,即
GUIApplicationPanel& currentPanel = currentPanels->at(panelIndex);
现在currentPanel
将引用到容器中指定索引处的GUIApplicationPanel
实例。
答案 1 :(得分:0)
对我来说,问题在于初始化。 _x
和_y
未在GUIApplicationPanel
的构造函数中初始化,并且可能具有任意值。如果某个面板没有更新,那么它将具有罕见的值。
修改强>:
根据您的评论,另一个问题可能是您按值保存LibXenonApplication
和GUIapplicationPanel
类型的变量。我建议你使用指针来保存那些面板的引用,而不是那些对象的副本。可能会出错。