使用Delete和Smart Pointer释放内存以及释放内存的正确方法

时间:2019-05-06 08:54:50

标签: c++ pointers memory smart-pointers

我正在为大学做一个项目,我试图找出如何正确删除内存的方法,以及我想出的删除方法是否与使用智能指针具有相同的效果。

这是一个班级,将容纳所有在公司和团队中工作的员工,这些员工和团队基本上都有指向某些员工的指针。

class Company
{
private:
    std::string companyInfo;
    std::vector<Employee * > employees;
    std::vector<Team *> teams;
public:
    Company();
    ~Company();

    std::string getCompanyInfo() const;
    void setCompanyInfo(const std::string & companyInfo);
    bool addEmployee(Employee * employee, const std::string & teamName);
    bool addTeam(Team * team);
    void printTeams() const;
    void printEmployees() const;
};

所以我的问题是:这是释放内存的一种正确方法吗?如果可以,它将提供与使用智能指针自动执行过程相同的结果。

Company::~Company()
{
    for (Employee * e : employees) {
        delete e;
    }

    employees.clear();

    for (Team * t : teams) {
        delete t;
    }

    teams.clear();
}

如果更好的做法是使用智能指针,我应该在我的特殊情况下使用唯一或共享指针。我对智能指针有一些看法,它们在作用域结束时会删除分配的内存,但是我真的很困惑何时结束。当公司的析构函数被调用时,会发生这种情况吗?

先谢谢您,如果我的问题看起来很愚蠢。

3 个答案:

答案 0 :(得分:3)

如果您不知道自己在做什么,就应该绝对不要在代码逻辑中写delete。那是规则。每当您违反此规则时,都应期望发生各种问题。换句话说:始终使用std容器+智能指针。

唯一指针::指针周围的简单包装,当其超出范围时将删除其下的资源。您不能复制唯一的指针,因为如果可以的话,谁将拥有该指针的所有权?谁将其删除?只能删除1个对象。

共享的指针:使复制成为可能,但要以(原子)计数器为代价,该计数器对引用同一指针的对象数进行计数。当计数器归零时,指针下的资源将被删除。

答案 1 :(得分:2)

  

这是释放内存的正确方法

假设容器是用new运算符填充的,

employees.push_back(new Employee());
teams.push_back(new Team());

然后是的,这是清理这些资源的正确方法。

  

...,如果是,它将提供与使用智能指针自动执行过程相同的结果。

通常是。您可以调整智能指针如何删除其管理的资源,但是默认行为是针对您情况的正确行为(调用delete)。

  

我应该使用唯一指针还是共享指针

首选应为std::unique_ptr。它比std::shared_ptr更有效率,并且对其管理对象的使用方式也有更多限制。但这有局限性,例如不能复制具有std::unique_ptr个数据成员的类(在您的情况下为Company)。使用std::shared_ptr可以缓解此问题,但语义却大不相同-复制Company对象意味着共享团队和员工。这可能不是您想要的。解决此问题的一种方法是使用std::unique_ptr,根据所谓的虚拟构造函数CompanyEmployee::clone()成员函数为Team::clone()实现复制和复制分配构造函数。 / p>

  

它们在作用域结束时删除分配的内存,但我真的很困惑何时结束

一个例子:

void someFunction()
{
    Company c;

    // stuff...

} // the scope ends here, ~Company will be called

答案 2 :(得分:1)

  

这是释放内存的正确方法

假设所有存储的指针都已使用new-expression进行了分配,并且假设所有指针仍然有效(即未悬挂),则析构函数就可以了。

清除向量是多余的。这些向量即将被销毁,因此无论如何它们的元素都将被清除。

但是,您的课程很可能坏了。它是可复制的,并且如果您进行复制,并且不从其中一个副本中删除指针,则这些对象的析构函数将删除相同的指针,这将导致不确定的行为。

您可以通过使用智能指针来解决此问题,并使析构函数更简单(您可以简单地使用隐式析构函数)。

  

我应该使用唯一指针还是共享指针

是的,你应该

您的代码展示了唯一的所有权-Company拥有EmployeeTeam唯一-因此,最简单的更改是使用唯一的指针。

  

我对智能指针有红色的看法,并且在作用域结束时它们会删除分配的内存,但是我真的很困惑何时结束。当公司的析构函数被调用时,会发生这种情况吗?

删除指针的是智能指针的析构函数。

当智能指针是局部变量时,它将在作用域末尾销毁。就像您的Company是局部变量一样,它会在作用域末尾销毁,并且其析构函数将运行。

当智能指针是成员时,在销毁超级对象时,销毁它。对于您而言,您将拥有一个智能指针向量,在这种情况下,当矢量被破坏时智能指针将被破坏,或者从该向量中删除智能指针。