C++对象保留?

C++ Object Retaining?

本文关键字:保留 对象 C++      更新时间:2023-10-16

我是一名Objective-C程序员,最近开始C++,我在代码的组织上偶然发现了这个问题:

std::list<char *> stuff = std::list<char *>();
thing *object = new thing(stuff);

stuff是我在类的生命周期内需要的对象(也就是说,直到它被破坏),如何避免丢失它?

在 Objective-C 上,我可以简单地在构造函数上调用-retain。C++?

当你不需要指针时,不要使用它们,也不要使用拥有原始指针(除非你有很好的理由)。

使用自动存储持续时间

std::list<char> stuff;
thing object{stuff};

thing的构造函数将std::list<char>作为其参数:

#include <utility> // for std::move
class thing {
public:
explicit thing(std::list<char> stuff_) : stuff(std::move(stuff_)) {}
private:
std::list<char> stuff;
};

如果这样做,thing的析构函数将在thing超出范围时被调用,隐式调用stuff的析构函数。许多好的C++书都非常详细地解释了这一点。

与Objective-C不同,C++使用RAII而不是引用计数。基本规则是:尽可能使用自动存储持续时间,避免原始拥有指针,并且除非您有充分的理由,否则不要使用new

通常的方法是在thing的构造函数中复制或移动到thingstuff

class thing {
public:
thing(std::list<char*> stuff) : stuff(std::move(stuff)) {}
private:
std::list<char *> stuff;
};

目前尚不清楚您将如何在示例中使用stuff,因此我将为您提供几个不同的选项。

  1. thing存储自己的stuff副本。
    在本例中,您的类存储类型为std::list<char*>的对象。

    class thing
    {
    public:
    thing(std::list<char*>& aList):m_list(alist){}
    std::list<char*> m_list;
    };
    

    构造时thing将创建stuff的副本并将其存储在类中。当对象被销毁时,它将自动释放m_list

  2. thing存储对stuff的弱引用。
    你的类将存储指针(std::list<char*>* m_list)或引用(std::list<char*>& m_list)。thing将能够以任何方式使用您的列表,但它不应该负责资源管理。如果列表的范围比thing小,那么您将留下一个挂起的引用。

    thing getThing()
    {
    std::list<char*> list1;
    thing object1(list1);
    return object1; //bad - list will be deallocated, object1 will have a hanging reference
    }
    
  3. thing存储指向stuff的共享指针。 这是最类似于目标 C 中retain的方法,C++没有自动引用计数。如果要存储具有共享所有权的对象引用,可以使用std::shared_ptrthing商店std::shared_ptr<std::list<char*>> m_list.

    std::shared_ptr<std::list<char*>> stuff = std::make_shared<std::list<char*>>();
    thing object(stuff); //reference count incremented, even if stuff is destroyed object will still hold a valid reference