2011-04-09 67 views
0

對於下面的代碼,當複製v時,Model類的成員不會被複制。爲boost指針容器調用基類的複製構造函數?

#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

(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 
+0

編譯器爲'SomeNewClass'生成的默認拷貝構造函數是不夠.. – Nawaz 2011-04-09 12:12:39

+0

是的,但萬一如果他有裏面一些指針,必須被深度複製,然後他可以繼續編輯它。我假設,「SomeNewClass」並不限於他所提到的。 – iammilind 2011-04-09 12:14:30

+0

Erm ...實際上懷疑當ModelInherit的拷貝被註釋掉時,容器會自動拷貝。但它不會做深層次的複製。也許解決方案在於克隆功能:http://www.boost.org/doc/libs/1_46_1/libs/ptr_container/doc/examples.html#objects-are-cloned-before-insertion-inserted-pointers-are擁有該容器的 – Nav 2011-04-11 04:35:13

1

調用基類拷貝構造很簡單:

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

Model(m)調用基類拷貝構造;參數m隱式轉換爲基類。

在基類複製構造函數中,您必須手動深度複製m.s