在C ++中设置和访问成员变量

时间:2011-09-19 09:55:29

标签: c++

我正在为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

2 个答案:

答案 0 :(得分:2)

问题在于您访问向量中元素的方式:

GUIApplicationPanel currentPanel = currentPanels->at(panelIndex);

这将获取元素的副本,因此您可以设置副本的属性,而不是容器中保存的项目。获取参考,然后您可以修改容器中的项目..

编辑:基于评论,因为您已经意识到std::vector<>::at()会返回引用,所以您需要做的是将上述内容更改为引用,即

GUIApplicationPanel& currentPanel = currentPanels->at(panelIndex);

现在currentPanel 引用到容器中指定索引处的GUIApplicationPanel实例。

答案 1 :(得分:0)

对我来说,问题在于初始化。 _x_y未在GUIApplicationPanel的构造函数中初始化,并且可能具有任意值。如果某个面板没有更新,那么它将具有罕见的值。

修改

根据您的评论,另一个问题可能是您按值保存LibXenonApplicationGUIapplicationPanel 类型的变量。我建议你使用指针来保存那些面板的引用,而不是那些对象的副本。可能会出错。