简体   繁体   中英

C++ calling constructor for passing new object causes missing data

So I have a class RadianButtonComponent and I want to have a vector contain an uncertain number of objects of RadianButtonComponent . However, I want to do something along the lines of -- myButtons.push_back(RadianButtonComponent(font, "text", ...)) However, when I do this, I lose some information. I know that calling the constructor like that will basically make a temporary object. However, when I try to pass font over (which is a pointer to an address) I lose that address even if the pointer is passed by reference from an outside source.

(To give some code to help explain)

class RadianButtonComponent
{
private:
    sf::Font myFont;
    sf::Text myText;
    /* ... */

public:
    RadianButtonComponent();
    RadianButtonComponent(sf::Font& font, std::string text, ...)
    {
        myFont = font;
        myText.setFont(myFont);
        myText.setString(text);
    }
    ~RadianButtonComponent();
};

int main()
{
    sf::Font font;
    font.loadFromFile("...");

    //No memory lost, font address not removed.
    RadianButtonComponent workingButton(font, "Text", ...);

    //Memory lost, font address not found.
    RadianButtonComponent brokenButton;
    brokenButton = RadianButtonComponent(font, "Text", ...);

    return 0;
}

Now I know that when the constructor is called like this it basically makes a temporary object of the class, however, if BrokenButton is set to this temporary object and its pointer to font is set to the address from the outside font source's address it should work (at least I think it should), but I still lose the address.

Why does this happen and how can this be fixed? Is there something more I should know about what happens when the constructor is called like this?

(I feel that I have given enough information, but if you need more code to help pinpoint the problem I will update it asap)

From the spec:

It is important to note that the sf::Text instance doesn't copy the font that it uses, it only keeps a reference to it. Thus, a sf::Font must not be destructed while it is used by a sf::Text (ie never write a function that uses a local sf::Font instance for creating a text).

So in the copy constructor, you must copy the font and then reset the font of the new object's myText.

Alternatively disable the copy constructor, and create a vector of smart pointers of your buttons.

You are not following the "rule of 3". Your class lacks a user-defined assignment operator and copy constructor to handle these sf_Font types. So when you do this:

RadianButtonComponent brokenButton;
brokenButton = RadianButtonComponent(font, "Text", ...);  // assignment operator is called

Then all bets are off when = is applied, as you're doing on the second line above. Since your explanation (and the other answer's explanation) of what an sf_Font is, your RadianButtonComponent may or may not be safely placed in a container such as std::vector . The object must have the correct copy semantics beforehand.

In other words, if this program does not work correctly, then you need to fix it so it does work before even considering placing it in a vector:

int main()
{
   RadianButtonComponent b1(font, "Text", ...);
   RadianButtonComponent b2 = b1;
   RadianButtonComponent b3(font, "Text2", ...);
   b3 = b1;
}

That program (and any program that can be a variant of the above) must be able to compile and run without any flaws (including clean up of memory).

If the program doesn't work, then the suggestion of using a vector of smart pointers is a possible solution instead of a vector<RadianButtonComponent> .

Thinking about this problem more, storing sf::Font inside an object is the wrong approach. I suggest you have a global std::map<std::string, sf::Font> data structure somewhere, which stores the fonts with their font name. (You could also use an int or enum id instead of a string). A button's constructor will take an sf::Font reference, which originates from this map, but does not copy it. Therefore all sf::Text objects will refer to the sf::Font instance stored permanently in your map.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM