我正在为大学做一个项目,我试图找出如何正确删除内存的方法,以及我想出的删除方法是否与使用智能指针具有相同的效果。
这是一个班级,将容纳所有在公司和团队中工作的员工,这些员工和团队基本上都有指向某些员工的指针。
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();
}
如果更好的做法是使用智能指针,我应该在我的特殊情况下使用唯一或共享指针。我对智能指针有一些看法,它们在作用域结束时会删除分配的内存,但是我真的很困惑何时结束。当公司的析构函数被调用时,会发生这种情况吗?
先谢谢您,如果我的问题看起来很愚蠢。
答案 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
,根据所谓的虚拟构造函数Company
和Employee::clone()
成员函数为Team::clone()
实现复制和复制分配构造函数。 / p>
它们在作用域结束时删除分配的内存,但我真的很困惑何时结束
一个例子:
void someFunction()
{
Company c;
// stuff...
} // the scope ends here, ~Company will be called
答案 2 :(得分:1)
这是释放内存的正确方法
假设所有存储的指针都已使用new-expression进行了分配,并且假设所有指针仍然有效(即未悬挂),则析构函数就可以了。
清除向量是多余的。这些向量即将被销毁,因此无论如何它们的元素都将被清除。
但是,您的课程很可能坏了。它是可复制的,并且如果您进行复制,并且不从其中一个副本中删除指针,则这些对象的析构函数将删除相同的指针,这将导致不确定的行为。
您可以通过使用智能指针来解决此问题,并使析构函数更简单(您可以简单地使用隐式析构函数)。
我应该使用唯一指针还是共享指针
是的,你应该
您的代码展示了唯一的所有权-Company
拥有Employee
和Team
唯一-因此,最简单的更改是使用唯一的指针。
我对智能指针有红色的看法,并且在作用域结束时它们会删除分配的内存,但是我真的很困惑何时结束。当公司的析构函数被调用时,会发生这种情况吗?
删除指针的是智能指针的析构函数。
当智能指针是局部变量时,它将在作用域末尾销毁。就像您的Company
是局部变量一样,它会在作用域末尾销毁,并且其析构函数将运行。
当智能指针是成员时,在销毁超级对象时,销毁它。对于您而言,您将拥有一个智能指针向量,在这种情况下,当矢量被破坏时智能指针将被破坏,或者从该向量中删除智能指针。