我有一个类使用一类指向派生对象的基指针,所以我需要有自己的析构函数来删除 vector 的元素以及自定义复制和赋值函数。我不完全确定实现如下结构并为其编写正确的复制和赋值构造函数和析构函数的首选方法。我可以请你指导我吗?我已经阅读和搜索了很多,但我仍然不确定。
class Base
{
public:
Base();
~virtual Base();
int a;
int type; // Derived1 or Derived2
std::string b;
...
}
class Derived1 : public Base
{
public:
Derived1();
Derived1(const Base* a);
virtual ~Derived1();
}
class Derived1
{
Derived1::Derived1(const Base *a) : Base(a)
{
}
}
class Derived2 : public Base
{
public:
Derived2();
Derived2(const Base* a);
virtual ~Derived2();
std::string d1;
std::string d2;
int d3;
}
class Derived2
{
Derived2::Derived2(const Base *a) : Base(a) {
this->d1 = ((Derived2*)a)->d1;
this->d2 = ((Derived2*)a)->d2;
this->d3 = ((Derived2*)a)->d3;
}
}
class A
{
public:
A();
~A();
A(const A& a);
A& operator = (const A& a);
std::string someString;
std::vector<Base*> vect;
}
A::~A() {
std::vector<Base*>::iterator it = vect.begin();
while (it != vect.end()) {
delete (*it);
it++;
}
A::A(const A &a)
{
someString = a.someString;
for(std::size_t i = 0; i < a.vect.size(); ++i {
someString = a.someString;
Base* base = a.vect.at(i);
if(base->type == base::TypeD1) {
base = new Derived1( a.vect.at(i) );
vect.push_back( base );
}
else {
base = new Derived2( a.vect.at(i) );
vect.push_back( base );
}
}
}
最佳答案
你在析构函数中的循环在实践中很好,而且是 通常的解决方案。形式上,这是未定义的行为,因为你 将对象留在 vector 中(指向已删除对象的指针) 不可复制,但实际上: vector 不会复制 他们除非你把它调整到更大的东西,或者插入或 删除它。如果你真的想避免 undefined 行为:
for ( auto current = vect.begin(); current != vect.end(); ++ current ) {
Base* tmp = *it;
*it = nullptr;
delete tmp;
}
但在这种情况下,我可能不会费心(并且 与大多数人相比,我往往对未定义的行为更敏感)。
关于C++ 复制构造函数清除 Derived* 的 vector<Base*>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23266629/