【问题标题】:Create object and prevent from being destructed创建对象并防止被破坏
【发布时间】:2020-03-05 17:47:08
【问题描述】:

我有一个班级

class ListOfControllers
{
public:
    ListOfControllers();        
    ~ListOfControllers();    
    QList<RmgController> rmgControllers;

    QJsonObject toJson() const;
    void fromJson(QJsonObject obj);
};

fromJson我想读取一个json并填写QList&lt;RmgController&gt; rmgControllers

void ListOfControllers::fromJson(QJsonObject obj)
{
    .
    .
    .
            rmgControllers.clear();
            for (...)
            {
                RmgController rmg;
                rmg.fillWithValues();//fill the object with values from json
                rmgControllers.push_back(rmg);
                //at this point the DESTRUCTOR of RmgController is being called and the filled values CLEARED
            }
}

当我离开对象创建的范围时,RmgController 的析构函数会引发并清除所有填充的值,因此列表 (rmgControllers) 包含一些具有默认值的对象,而不是从 json 读取的值。

【问题讨论】:

标签: c++ list qt class constructor


【解决方案1】:

您的选项取决于RmgController 是否具有移动感知功能(如果您为其提供了自定义复制运算符和/或自定义删除器,则可能不是)。如果没有,您可以使用emplace_back(假设QList 具有与std::list 类似的接口)。

类似这样的:

    rmgControllers.clear();
    for (...)
    {
        // emplace default-constructed object at end of list
        rmgControllers.emplace_back();  

        // reference added controller
        RmgController&  rmg = rmgControllers.back(); 

        //fill the object with values from json
        rmg.fillWithValues();
    }

如果RmgController 具有移动感知能力,您只需将其移至列表末尾即可。

    rmgControllers.clear();
    for (...)
    {
        // create controller
        auto rmg = RmgController(); 

        //fill the object with values from json
        rmg.fillWithValues();

        // move new controller to end of list
        rmgControllers.push_back(std::move(rmg));  
    }

【讨论】:

  • 没有emplace_back(),第二个解决方案也没有工作,在push_back之后调用了析构函数
  • @mammadalius 嗯,真可惜。您可能需要考虑使用std::list
【解决方案2】:

当您调用push_back 将值推送到向量中时,如果选择了 const 左值引用签名,则该值将复制到其中。

为防止这种情况发生,您可以使用emplace_back 就地构造向量中的值,或调用std::move 在推回该值时移动该值。

但是,在您的情况下,RmgController 类的复制构造函数似乎没有正确定义。如果你有一个指针类型的成员变量,你必须定义自定义的复制构造函数(加上复制赋值/移动赋值和构造函数/析构函数,这称为五法则),否则两个实例同一个类可能有指针都指向同一个共享资源/状态,这会导致错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 2014-05-26
    • 1970-01-01
    • 2010-12-25
    相关资源
    最近更新 更多