Вызывать конструктор копирования базового класса для контейнеров указателя наддува? - PullRequest
0 голосов
/ 09 апреля 2011

Для приведенного ниже кода при копировании 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, контейнер указателей автоматически скопирует переменную i в классе Model. Грустная часть в том, что SomeNewClass * s не копируется. Нет глубокого копирования.

Итак, мои вопросы:

  • Вы знаете, как вызвать копию конструктор класса Model в код выше?
  • Как обеспечить глубокое копирование, когда контейнер указателя автоматически копирует переменные, так что копируется даже переменная 'a' SomeNewClass?

Ответы [ 2 ]

2 голосов
/ 09 апреля 2011

(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 голос
/ 09 апреля 2011

Вызывать конструктор копирования базового класса легко:

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

Model(m) вызывает конструктор копирования базового класса;параметр m неявно преобразуется в базовый класс.

В конструкторе копирования базового класса необходимо выполнить глубокое копирование вручную m.s.

...