简体   繁体   English

派生类数组的C ++构造函数副本

[英]C++ constructor copy of an array of derived classes

Although there are numerous posts with managing pointers in copy constructors, i did not find the suitable answer to realize the following properly. 尽管在复制构造函数中有许多带有管理指针的文章,但我没有找到合适的答案来正确实现以下内容。

An object 'a' of class A stores a 'tab' array of elements that are pointers to elements of either type B1 or B2, both derived from class B. 类A的对象“ a”存储元素的“制表符”数组,这些数组是指向类B1或B2的元素的指针,均从类B派生。

I want to save a copy of 'a' (to restore it later) by calling a copy constructor. 我想通过调用副本构造函数来保存“ a”的副本(以便稍后还原)。 My problem is to allocate memory in this copy constructor, to make a copy of the contents of the 'tab[i]' elements. 我的问题是在此副本构造函数中分配内存,以复制'tab [i]'元素的内容。

There must be a canonical way of doing this (i suppose without invoking <dynamic_cast> to determine if this is type B1 or B2). 必须有一种规范的方法(我想无需调用<dynamic_cast>来确定它是B1还是B2类型)。

This is the MWE i have build to illustrate the question: 这是我用来说明问题的MWE:

#include <iostream>
using namespace std;


//-----------------------
class B {
public:
  virtual void display()=0;
};

//-----------------------
class B1 : public B {
public:
  B1() : val(1)  // ctor
  {}  
  void display() {
    cout << val << endl;
  }
private:
  int val;

};
//-----------------------
class B2 : public B {
public:
  B2() : val(2)  // ctor
  {}
  void display() {
    cout << val << endl;
  }
private:
  int val;

};

//---------- A -------------
class A {

public:
  A () {            // ctor
    tab = new B * [2];
    tab[0] = new B1;
    tab[1] = new B2;
  } 

  A (A const &orig)         // copy ctor
    : tab(orig.tab)
  {          
    // ... HOW should i make a copy of the tab[i] elements ?...
    // ... as i do not know if tab[i] is type B1 or B2 ...
  }

  void display() {
    tab[0]->display();   
    tab[1]->display();   
  }


private:
  B ** tab;
};




//------M A I N ---------

int main() {
  A a;
  a.display();

  return 0;
}

You cannot do this without determining the concrete type of B, either by using dynamic_cast , or by calling a virtual method, which is then dispatched to the concrete type. 您不能通过使用dynamic_cast或调用虚拟方法(然后将其分派到具体类型)来确定B的具体类型,而不执行此操作。

This is typically resolved by using the "clone" pattern on the interface of B , adding the function to B : virtual B* clone() const = 0; 通常可以通过在B接口上使用“克隆”模式来解决此问题,并将函数添加到Bvirtual B* clone() const = 0; with each implementation allocating and returning an appropriate copy of itself. 每个实现都分配并返回其自身的适当副本。

Also notice you are not deleting any of the memory allocated in your example. 还要注意,您没有删除示例中分配的任何内存。 Remember to do this in destructors, or better use smart pointers like std::unique_ptr! 记住要在析构函数中执行此操作,或者最好使用智能指针(如std :: unique_ptr)!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM