为boost指针容器调用基类的复制构造函数?

时间:2011-04-09 11:50:35

标签: c++ copy-constructor deep-copy pointer-container

对于下面的代码,当复制v时,不会复制Model类的成员。

#include <boost/ptr_container/ptr_vector.hpp>
#include <iostream>
using namespace std;

    class SomeNewClass
    {
    public:
       int a;
    };

    class Model
    {
    public:
       int i;
       SomeNewClass* s;//A deep copy won't happen here automatically

       Model() {}
       Model(const Model& m):i(m.i)
       {
        cout<<"Model Copy ctor invoked"<<endl;
       }
    };

    class ModelInherit : public Model
    {
    public:
       int j;

       ModelInherit() {}
       ModelInherit(const ModelInherit& m):j(m.j)
       {
          //i=m.i;//I don't want to copy like this. I want the copy ctor of Model to be invoked
          cout<<"ModelInherit Copy ctor invoked"<<endl;
       }
    };

    int main()
    {
       boost::ptr_vector<ModelInherit> v;
       v.push_back(new ModelInherit);
       v[0].j = 10;
       v[0].i = 20;
       v[0].s = new SomeNewClass();
       v[0].s->a = 99;

       boost::ptr_vector<ModelInherit> v2( v );
       cout<< v2[0].j <<endl;
       cout<< v2[0].i <<endl;
       //cout<< v2[0].s->a <<endl;//segmentation fault
    }

重要的是要注意,如果注释掉ModelInherit的复制构造函数,那么指针容器会自动复制Model类中的i变量。可悲的是,“SomeNewClass * s”不会被复制。没有深刻的副本。

所以我的问题是:

  • 您知道如何调用副本吗? 中的Model类的构造函数 上面的代码?
  • 当指针容器自动复制变量以便甚至复制SomeNewClass的'a'变量时,如何确保深层复制?

2 个答案:

答案 0 :(得分:2)

(1)要调用模型复制构造函数,请更改您的ModelInherit复制构造函数,如下所示:

ModelInherit(const ModelInherit& m): Model(m), j(m.j) {}

(2)深层复制可以这样做:

Model(const Model& m): i(m.i), s(0)
{
  if(m.s != 0)
    this->s = new SomeNewClass(*(m.s));
  cout<<"Model Copy ctor invoked"<<endl;
}

并为SomeNewClass声明一个复制构造函数,如下所示:

SomeNewClass(const SomeNewClass &copy) : a(copy.a)
{
  cout<<"SomeNewClass Copy ctor invoked"<<endl;
}

不要忘记在析构函数中释放Model::s,否则会泄漏内存:

~Model () { delete this->s; }  // it's ok if s = 0

答案 1 :(得分:1)

调用基类copy-constructor很简单:

ModelInherit(const ModelInherit& m): Model(m), j(m.j) {}
                                  //^^^^^^^^ note this

Model(m)调用基类copy-constructor;参数m隐式转换为基类。

在基类复制构造函数中,您需要手动深层复制m.s