繁体   English   中英

将emplace_back对象转换为std :: list的正确方法

[英]Proper way to emplace_back object into std::list

我有一个包含各种成员的类(主要是int,float和一些动态容器)。 我有一个std :: list myclassobjects。 在设置所有参数后,在此类的构造函数中调用

myclassobjects.emplace_back(*this)

这有效,并且似乎不会引起分配问题; 我从来没有sigsegv问题或类似问题。 但是,我并不完全相信这是正确的做法,或者它不会导致缓慢的刻录内存泄漏。

此方法安全使用还是会导致内存泄漏? 如果是,构造对象并将其立即放入std :: list的“正确”方法是什么?

首先, emplace_back通过转发其参数在适当的位置构造一个对象。 因此,您最终要做的是使用参数*this调用类的副本构造函数。

我试图考虑一种情况,其中需要将对象添加到构造函数内部的列表中,而我遇到了困难。 我认为还有更好的选择。

从构造函数外部将其放置在列表中

只需如下创建即可。

myclassobjects.emplace_back(/*constructor params*/);

在C ++ 17中,这甚至返回对新创建对象的引用

MyClass& myclass_ref = myclassobjects.emplace_back(/*constructor params*/);
do_something_with_my_class_object(myclass_ref);

这是最干净,最有效的方法。 它具有额外的好处,即您可以创建本地对象,而无需根据需要将其添加到列表中。

使用工厂方法将其添加到列表中

如果绝对必须在列表中包含每个对象,并且您不希望它成为副本,请使用静态工厂方法。 如果该列表和被叫方必须共享所有权,则可以使用std::shared_ptr的列表并执行以下操作。

MyClass {
private:
    MyClass();    // private constructor forbids on the stack variables

public:
    static std::shared_ptr<MyClass> create_instance() {
        auto ptr = make_shared<MyClass>();    // We can access the constructor here
        myclass_objects.emplace_back(ptr);
        return ptr;
    }
}

另一方面,如果保证您的列表在对象上超出了被调用方的处理程序,则更合适的方法是拥有一个std::unique_ptr列表,用于保存对象并返回对其的引用。

MyClass {
private:
    MyClass();    // private constructor forbids on the stack variables

public:
    // pre C++17
    static MyClass& create_instance() {
        auto ptr = make_unique<MyClass>();
        auto& ref = *ptr;    // Store ref before we move pointer
        myclass_objects.emplace_back(std::move(ptr));
        return ref;
    }

    // C++17
    static MyClass& create_instance() {
        auto ptr = make_unique<MyClass>();
        return *(myclass_objects.emplace_back(std::move(ptr)));
    }
}

当然,这些示例仅涵盖默认构造函数。 因为通常将需要使用更多的构造函数,所以可能需要模板化的create_instance并将其参数转发给构造函数。

确实不可能将对象存储在std::list或任何其他容器中。 根据对象的标准定义,对象是存储区域 存储的区域不能存储,它只是

假设X是一个现有对象。 容器本身不能存储X,但是可以某种方式与X相关的值。 有两种选择。

  1. 存储X的副本
  2. 将(智能)指针或引用包装存储到X。

由于您要使用*this ,因此要存储副本。 这可能是您需要的,也可能不是。

要存储裸露的指针,您必须要emplace_back(this) ,当然emplace_back(this)更改列表的类型。 这很危险,因为当X不再存在时,您的列表可能仍然有指向它的悬空指针。 您需要确保它不会发生。

您可能要考虑将共享指针,但如果你想通过继承,使之enable_shared_from_this ,要知道, shared_from_this是在构造函数中使用危险的事情

暂无
暂无

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

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