【问题标题】:How to add new object instances to std::list without 'new'如何在没有“new”的情况下将新对象实例添加到 std::list
【发布时间】:2015-11-08 18:20:30
【问题描述】:

在这里阅读了几十个关于列表、向量、new 运算符、RAII 和this 非常好的内存分配描述的答案,我仍然无法想象满足以下需求的实际实现。请注意,我在 .net 及其内存管理方面最有经验,如果这有助于指导任何答案的话。

基本上,我有一个类(比如class RecordFile {})以特定格式封装文本文件。每行相当于我想添加到RecordList 实例拥有的std::list<Record> 的记录,其中class Record 从文件中的单行捕获数据。

RecordList 类中,我有一个方法RecordList::Read() 逐行读取文件,创建一个新的Record 实例并将其添加到RecordList 实例拥有的列表中。

在这个Read() 方法中,有一个循环遍历文件的行,创建新的Record 实例。显然,一旦读取文件并且 Read() 方法完成,我希望记录列表保留在 RecordList 对象中,但如果不使用“新”运算符,我看不到如何做到这一点。

如何在不违反看似基本规则的情况下在 c++ 中执行此任务?在 .net 中,这将是微不足道的,并且完全按照所说的执行,不会对性能或内存泄漏造成任何风险。我知道 c++ 是一种不同的野兽,我正在努力掌握它。

【问题讨论】:

    标签: c++ list object memory-management instantiation


    【解决方案1】:

    list 容器会为您处理内存管理。

    只需像这样在 RecordList 类上创建一个 list 成员:

    std::list<Record> records_;
    

    然后使用emplace_back简单地添加行:

    records_.emplace_back(<whatever parameters `Record` constructor takes>);
    

    RecordList 被销毁时,list 及其所有元素也会被销毁。

    【讨论】:

    • 这很酷,所以元素被它们的容器紧紧拥有。这是 emplace_* 方法的全部意图吗?对于所有元素都属于同一类族而不是一个具体类型的列表,这是否会以同样的方式工作?
    • @JCollins emplace 方法的目的是在现场构造对象,而不是在其他地方构造对象然后将其复制到容器中。不,它不适用于一系列对象,因为您需要智能指针 (unique_ptr/shared_ptr) 来处理您的生命周期。不用new也可以创建并为它们分配内存,查看函数make_unique/make_shared
    • 谢谢imreal,好像是c++14,这个标准比较普遍吗?
    • @JCollins 我认为 make_unique 是 C++14(但它在 gcc 4.9 上),make_shared 是 C++11,它被很好地采用了。无论如何,您都可以非常安全地使用new 初始化unique_ptr
    猜你喜欢
    • 1970-01-01
    • 2015-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多