创建对象并防止被破坏

Create object and prevent from being destructed

本文关键字:创建对象      更新时间:2023-10-16

我有一个类

class ListOfControllers
{
public:
ListOfControllers();        
~ListOfControllers();    
QList<RmgController> rmgControllers;
QJsonObject toJson() const;
void fromJson(QJsonObject obj);
};

fromJson中,我想读取一个json并填充QList<RmgController> 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的析构函数会引发并清除所有填充的值,因此List(rmgControllers(包含一些具有默认值的对象,而不是从json中读取的值。

您的选项取决于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));  
}

当您调用push_back将一个值推送到向量中时,如果选择了const-l-value引用签名,该值将被复制到其中。

为了防止这种情况,可以使用emplace_back在向量中原位构造值,或者在将值推回时调用std::move来移动值。

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