繁体   English   中英

用于传递新对象的C ++调用构造函数导致数据丢失

[英]C++ calling constructor for passing new object causes missing data

所以我有一个RadianButtonComponent类,并且我想让一个包含不确定数量的RadianButtonComponent对象的RadianButtonComponent 但是,我想按照myButtons.push_back(RadianButtonComponent(font, "text", ...))但是,这样做时,我会丢失一些信息。 我知道调用这样的构造函数基本上会创建一个临时对象。 但是,当我尝试传递字体(这是指向地址的指针)时,即使指针是通过外部来源的引用传递的,我也会丢失该地址。

(给出一些代码来帮助解释)

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

现在我知道,当像这样调用构造函数时,它基本上是该类的一个临时对象,但是,如果将BrokenButton设置为该临时对象,并且将其指向字体的指针设置为来自外部字体源地址的地址,则它应该可以工作(至少我认为应该这样),但是我仍然丢失地址。

为什么会发生这种情况,如何解决? 关于像这样的构造函数调用时会发生什么,我是否应该进一步了解?

(我认为我已经提供了足够的信息,但是如果您需要更多代码来帮助查明问题,我将尽快对其进行更新)

从规格:

重要的是要注意sf::Text实例不会复制它使用的字体,它只会保留对其的引用。 因此,在sf::Font sf::Text使用sf::Font不得对其进行破坏(即,切勿编写使用本地sf::Font实例创建文本的函数)。

因此,在复制构造函数中,您必须复制字体,然后重置新对象的myText的字体。

或者禁用复制构造函数,并创建按钮的智能指针向量。

您没有遵循“ 3条规则”。 您的类缺少用户定义的赋值运算符和复制构造函数来处理这些sf_Font类型。 因此,当您执行此操作时:

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

然后,如上第二行所述,当应用=时,所有赌注都关闭。 由于您对sf_Font的解释(以及其他答案的解释),您的RadianButtonComponent可能会或可能不会安全地放置在诸如std::vector类的容器中。 该对象必须事先具有正确的复制语义。

换句话说,如果该程序无法正常运行,那么您需要对其进行修复,以使其能够正常工作甚至不考虑将其放置在向量中:

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

该程序(以及可以作为上述程序的变体的任何程序) 必须能够编译和运行而没有任何缺陷(包括清除内存)。

如果程序不起作用,则建议使用智能指针矢量来代替vector<RadianButtonComponent>

多考虑这个问题,将sf :: Font存储在对象中是错误的方法。 我建议您在某处有一个全局std::map<std::string, sf::Font>数据结构,该结构存储带有字体名称的字体。 (您也可以使用int或enum id代替字符串)。 按钮的构造函数将使用一个sf :: Font引用,该引用源自此映射,但不会复制它。 因此,所有sf :: Text对象都将引用永久存储在地图中的sf :: Font实例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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