2013-12-18 43 views
0

我有以下类为测试!Niether复制也不移动构造函数调用在c + +

class ArrayClass 
{ 
private: 
    int isize; 
    double* p ; 
public: 
    ArrayClass(int num_ =1):isize(num_),p(new double[num_]) 
    { 
     cout << "constructor with num!!" << endl ; 
     for(int idx=0;idx<num_;idx++) 
     { 
      p[idx] = 0.0 ; 
     } 
    } 
    ArrayClass(const ArrayClass& m) //copy constructor 
    { 
     cout << "copy constructor!!" << endl ; 
     isize = m.getsize() ; 
     p = new double[isize] ; 
     std::copy(m.getaddr(), m.getaddr() + m.getsize(), p); 
    } 
    ArrayClass& operator=(const ArrayClass& m) //copy assignment 
    { 
     cout << "copy assignment!!" << endl ; 
     if(this != &m) 
     { 
      int msize = m.getsize() ; 
      if(isize != msize) 
      { 
       delete []p ; 
       p = 0x00 ; 
       p = msize ? new double[msize] : 0x00 ; 
       isize = msize ; 
      } 
      std::copy(m.getaddr(), m.getaddr() + msize, p); 
     } 
     return *this ; 
    } 
    ArrayClass& operator=(ArrayClass&& m) 
    { 
     cout << "Move assignment!!" << endl ; 
     isize = m.getsize() ; 
     p = m.getaddr() ; 
     m.initialize() ; 
     return *this ; 
    } 
    ArrayClass(ArrayClass&& m) 
    { 
     cout << "Move Constructor!!" << endl ; 
     isize = m.getsize() ; 
     p = m.getaddr() ; 
     m.initialize() ; 
    } 
    ~ArrayClass() 
    { 
     cout << "desctrutor!!" << endl ; 
     delete []p ; 
    } 
    void initialize(){ isize=0; p=0x00; } 
    int getsize() const { return isize; } 
    double* getaddr() const { return p; } 
    double& operator[](int i) 
    { 
     if(i >= isize) 
      throw "the bound is wrong!!" ; 
     return p[i] ; 
    } 
    const double& operator[](int i) const 
    { 
     if(i >= isize) 
      throw "the bound is wrong!!" ; 
     return p[i] ; 
    } 
    void Print(void) 
    { 
     for(int idx=0;idx<isize;idx++) 
      cout << p[idx] << " " ; 
     cout << endl ; 
    } 
} ; 

ArrayClass func() 
{ 
    ArrayClass m(10) ; 
    for(int idx=0;idx<10;idx++) 
     m[idx] = idx * idx + 1 ; 
    return m ; 
} 

在g ++ 4.4.6在RedHat Linux上使用g ++编译--std =的C++ 0x x.cpp -o x.exe

的follwoing是我所期待的:

ArrayClass m2(std::move(func())) ; 
m2.Print() ; 

输出:

constructor with num!! 
Move Constructor!! 
desctrutor!! 
1 2 5 10 17 26 37 50 65 82 
desctrutor!! 

但是下面是不是我所期待:

ArrayClass m2(func()) ; 
m2.Print() ; 

输出:

constructor with num!! 
1 2 5 10 17 26 37 50 65 82 
desctrutor!! 

我预计应该有 “拷贝构造函数!” ,我很好奇,没有复制构造函数调用,也没有在这个测试中调用的构造函数,m2.Print()的答案是正确的?

+2

每天有多少个复制/移动elision问题? – texasbruce

+0

而且你也应该期望通过一个prvalue时移动建设。 – texasbruce

+0

如果使用GCC选项“-fno-elide-constructors”进行编译,会发生什么情况?这应该给你你的答案。 –

回答

2

这就是所谓的复制elision(虽然你基本上在这里删除移动操作)。如果语义保持不变,您可以在适当位置构造对象。

+0

从技术上讲,即使当操作失效时,它仍被称为* copy elision *。 12.8/31 * [...]这种复制/移动操作的缩写,称为复制删除* –

+0

http://definedbehavior.blogspot.tw/2011/08/value-semantics-copy-elision.html这个网页真的解释了很多复制elision!优秀作品 !! – barfatchen