适当释放 Base class 指针向量的内存,它是派生 class 的成员
Proper memory freeing of vector of Base class pointers, which is a member of a derived class
假设我有以下 classes:
Base.hpp
:
class Derived;
class Base {
protected:
Derived *boss;
//other things
public:
Base(); constuctor with irrellevant parameters
virtual ~Base(); // after confirmation from the comments,
//I made the destructor virtual but I still experience crashes due to segmentation fault
// other things
};
Base.cpp
:
Base::Base() {}//irrelevant
Base::~Base() {
delete this->boss; // I am afraid there might be a bug here
// the Derived class also has this member which points to the instace of the object itself,
//therefore, when calling the destructor, I am deleting the object itself, instead of just its member
}
Derived.hpp
:
class Derived : public Base {
private:
std::vector<Base *> employees;
// other things
public:
Derived();
~Derived();
// I'd like to make this method add the object to the employees vector without making a copy
void addEmployee(Base *employee, double salary);
// I'd like to make this method remove the object from the vector without destroying it, so that it could be given another boss in the future
void removeEmployee(const std::string &name);
};
Derived.cpp
:
Derived::Derived(const std::string &name, const double salary) : Base(name) {
this->boss = this; //required by my assignment to be that way
this->salary = salary;
}
Derived::~Derived() {
for (auto employee:this->employees) {
// if I don't delete the pointers, there will be a memory leak
// but If I delete them, I will also be destroying the employees Base class instances
// this->removeEmployee(this->employees->getName()); doesn't solve my problem either
delete employee;
}
this->team.clear();
}
void Derived::addEmployee(Base *employee, const double salary) {
if (employee != nullptr) {
employee->setBoss(this); // a method which sets 'Derived* boss' member of Base class to this Derived instance
this->team.push_back(developer); //add the object to the vector of employees
this->team.back()->setSalary(salary);
}
}
void Derived::removeEmployee(const std::string &name) {
for (int i = this->employees.size() - 1; i > -1; i--) {
// check for the first name match in reversed order of addition
if (this->employees[i]->getName() == name) {
// set the boss member of the Base instance to nullptr, i.e the Base no longer has a boss
this->employees[i]->setBoss(nullptr);
// if I don't delete the pointer, the program experiences even more crashes
// but that way I also delete the Base class instance, which I want to "live"
delete this->employees[i];
// remove the pointer from the vector
this->employees.erase(this->team.begin() + i);
// since a match has been found an the employee has been removed, no need to keep on searching
break;
}
}
}
此结构和实现是强制性的。如果我有选择权,我根本不会让 Derived class 继承,因此我会完全避免指针。但我无法选择。
所以我有两个问题:
- 我应该如何实现内存释放,这样我就不会得到
segmentation fault
并正确删除所有分配的内存?
- 是否可以将
Base
class 指针放入 Derived
class 向量中
当我不制作副本也不破坏对象
从向量中删除它们?这个想法是拥有 Base class 对象,其存在不依赖于 Derived
class 对象的存在。
如果这个问题已经被问到,我深表歉意。我无法在任何地方找到答案。
编辑:我通过在派生 class.
的析构函数中将 Derived class boss 指针更改为不同于自身的其他对象来修复崩溃
删除 Base::~Base()
定义中的 delete this->boss;
。假设 Base
个模范员工和 Derived
个模范老板,这相当于老板在任何员工离职时失去工作;这没有意义,如果一个 Derived
对象有员工,则在销毁时将不可避免地发生分段错误。
我怀疑你观察到 ~Base()
和 ~Derived()
每次销毁 Derived
对象被多次调用的原因是因为 this->boss
是 delete
d,它的 employees
/team
向量被释放,因此在基于范围的 for
循环中使用的迭代器变得无效。
假设我有以下 classes:
Base.hpp
:
class Derived;
class Base {
protected:
Derived *boss;
//other things
public:
Base(); constuctor with irrellevant parameters
virtual ~Base(); // after confirmation from the comments,
//I made the destructor virtual but I still experience crashes due to segmentation fault
// other things
};
Base.cpp
:
Base::Base() {}//irrelevant
Base::~Base() {
delete this->boss; // I am afraid there might be a bug here
// the Derived class also has this member which points to the instace of the object itself,
//therefore, when calling the destructor, I am deleting the object itself, instead of just its member
}
Derived.hpp
:
class Derived : public Base {
private:
std::vector<Base *> employees;
// other things
public:
Derived();
~Derived();
// I'd like to make this method add the object to the employees vector without making a copy
void addEmployee(Base *employee, double salary);
// I'd like to make this method remove the object from the vector without destroying it, so that it could be given another boss in the future
void removeEmployee(const std::string &name);
};
Derived.cpp
:
Derived::Derived(const std::string &name, const double salary) : Base(name) {
this->boss = this; //required by my assignment to be that way
this->salary = salary;
}
Derived::~Derived() {
for (auto employee:this->employees) {
// if I don't delete the pointers, there will be a memory leak
// but If I delete them, I will also be destroying the employees Base class instances
// this->removeEmployee(this->employees->getName()); doesn't solve my problem either
delete employee;
}
this->team.clear();
}
void Derived::addEmployee(Base *employee, const double salary) {
if (employee != nullptr) {
employee->setBoss(this); // a method which sets 'Derived* boss' member of Base class to this Derived instance
this->team.push_back(developer); //add the object to the vector of employees
this->team.back()->setSalary(salary);
}
}
void Derived::removeEmployee(const std::string &name) {
for (int i = this->employees.size() - 1; i > -1; i--) {
// check for the first name match in reversed order of addition
if (this->employees[i]->getName() == name) {
// set the boss member of the Base instance to nullptr, i.e the Base no longer has a boss
this->employees[i]->setBoss(nullptr);
// if I don't delete the pointer, the program experiences even more crashes
// but that way I also delete the Base class instance, which I want to "live"
delete this->employees[i];
// remove the pointer from the vector
this->employees.erase(this->team.begin() + i);
// since a match has been found an the employee has been removed, no need to keep on searching
break;
}
}
}
此结构和实现是强制性的。如果我有选择权,我根本不会让 Derived class 继承,因此我会完全避免指针。但我无法选择。 所以我有两个问题:
- 我应该如何实现内存释放,这样我就不会得到
segmentation fault
并正确删除所有分配的内存? - 是否可以将
Base
class 指针放入Derived
class 向量中 当我不制作副本也不破坏对象 从向量中删除它们?这个想法是拥有 Base class 对象,其存在不依赖于Derived
class 对象的存在。
如果这个问题已经被问到,我深表歉意。我无法在任何地方找到答案。
编辑:我通过在派生 class.
的析构函数中将 Derived class boss 指针更改为不同于自身的其他对象来修复崩溃删除 Base::~Base()
定义中的 delete this->boss;
。假设 Base
个模范员工和 Derived
个模范老板,这相当于老板在任何员工离职时失去工作;这没有意义,如果一个 Derived
对象有员工,则在销毁时将不可避免地发生分段错误。
我怀疑你观察到 ~Base()
和 ~Derived()
每次销毁 Derived
对象被多次调用的原因是因为 this->boss
是 delete
d,它的 employees
/team
向量被释放,因此在基于范围的 for
循环中使用的迭代器变得无效。