C++ 复制构造函数清除 Derived* 的 vector<Base*>

标签 c++ copy-constructor derived-class base-class

我有一个类使用一类指向派生对象的基指针,所以我需要有自己的析构函数来删除 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/

相关文章:

c++ - 使用 CvPoints vector 时为 "no matching function for call to min_element"(opencv)

c++ - 返回在transform中用lambda构造的对象

c++ - 为什么在声明移动分配时复制分配没有被删除?

c++ - 如何使用智能指针为单链表实现复制构造函数

c# - .net 根据参数类型选择了错误的调用方法

c++ - 区分 C++ 中基指针 vector 中的派生对象

c++ - boost interprocess file_lock不适用于多个进程

c++ - C++中的十六进制到字符串的转换

c++ - 包含原子的类的 std::vector

c# - XML 序列化 : The type of the argument object 'Sw' is not primitive