http://definedbehavior.blogspot.tw/2011/08/value-semantics-copy-elision.html

 

This elision of copy operations is permitted in the following circumstances (which may be combined to eliminate multiple copies):

  • in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object with the same cv-unqualified type as the function return type, the copy operation can be omitted by constructing the automatic object directly into the function’s return value

  • when a temporary class object that has not been bound to a reference (12.2) would be copied to a class object with the same cv-unqualified type, the copy operation can be omitted by constructing the tempo- rary object directly into the target of the omitted copy

 

copy slision 可以讓程式不過度使用 constructor ,   這有助於 performance , 例如 :

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

ArrayClass m2(func()) ;

本來應該呼叫  move constructor ,  但是 compiler 會幫你做 copy/move elision , 所以比起

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

效率更高 !!!

http://stackoverflow.com/questions/20649577/niether-copy-nor-move-constructor-called-in-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 ;
}

ArrayClass m2(func()) ;  will output :

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

 

ArrayClass m2(std::move(func())) ;  will output :

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

 

arrow
arrow
    全站熱搜

    hedgezzz 發表在 痞客邦 留言(0) 人氣()