开发者

Setting and accessing member variables in C++

I'm writing an open source project for the Xbox 360, it's my first time using C++ and I'm obviously doing something (Most likely many things) wrong.

My specific problem at the moment is that I create many instances of a class, passing in a reference to an object in the constructor, and setting a member variable to that object.

Later, when I access these objects, the member variable does not contain the object I assigned to it in the constructor.

Also, these objects have an Update(float x, float y) method, in this method I simply assign the x and y to member variables _x and _y.

When I access these values later, they are garbage.

I'm going to try post the relevant code here, but there may be something I miss, so just in case here is a link to the github project Github - Xenu.

The class I'm referring to is source/GUIApplicationPanel and the instantiating/using of them is in source/GUIManager.

Here is the object I am instantiating many instances of:

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());
}

And here is the code that creates them:

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));
}

Here is the code that updates them:

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++;
            }
        }
    }

And lastly here is the code that accesses values on them:

for(vector<GUIApplicationPanel>::iterator iter = currentPanels->begin(); iter != currentPanels->end(); ++iter) {
    iter->draw();
}

To be honest I'm all out of ideas - Acessing the application variable on a panel anywhere other than the constructor results in it being garbage, and likewise with _x and _y (Other than in the update method).

I put some logging in, so a line will be开发者_运维问答 logged in the update method of the panel logging the values of _x and _y after they've been set, as well as showing the name of the application (Which comes out blank in the log).

A line will also be logged when the draw method is called showing the current values of _x, _y and 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


The problem lies in the way you access the elements in the vector:

GUIApplicationPanel currentPanel = currentPanels->at(panelIndex);

This obtains a copy of the element, so you set the attributes of the copy, not the item held in the container. Obtain a reference and then you can modify the item in the container..

EDIT: Based on comment, as you've realised std::vector<>::at() return a reference, so what you need to do is change the above to be a reference, i.e.

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

Now currentPanel refers to the instance of GUIApplicationPanel at the specified index in the container.


Seems to me that the problem is with initialization. _x and _y are not initialized in the constructor of GUIApplicationPanel, and may have arbitrary values. If, by chance, a panel is not updated, it will have that rare values.

EDIT:

As per your comment, another problem could be that you hold variables of type LibXenonApplication and GUIapplicationPanel by value. I suggest you to use pointers to hold references to those panels instead of copies of those objects. There may lay your errors.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜