Конструктор Move и конструктор неконстантного копирования - PullRequest
0 голосов
/ 14 марта 2012

Я новичок в конструкторе перемещения, я провел опрос на некоторых сайтах и ​​попытался использовать бета-версию Visual Studio 11 Express ..

Ниже приведен мой код тестирования ...

#include <iostream>

using namespace std;

class Foo
{
public:
    Foo()
      : Memory(nullptr)
    {
        cout<<"Foo Constructor"<<endl;
    }
    ~Foo()
    {
        cout<<"~Foo Destructor"<<endl;
        if(Memory != nullptr)
            delete []Memory;
    }
    Foo(Foo& rhs)
      : Memory(nullptr)
    {
        cout<<"Copy Constructor"<<endl;

        //allocate
        //this->Memory = new ....
        //copy 
        //memcpy(this->Memory, rhs.Memory...);
    }

    Foo& operator=(Foo& rhs)
    {
        cout<<"="<<endl;
    }
    void* Memory;

    Foo(int nBytes) { Memory = new char[nBytes]; }

    Foo(Foo&& rhs)
    {
        cout<<"Foo Move Constructor"<<endl;
        Memory = rhs.Memory;
        rhs.Memory = nullptr;
    }
};

Foo Get()
{
    Foo f;
    return f; 
    //return Foo();
}
void Set(Foo rhs)
{
    Foo obj(rhs);
}
int main()
{
    Set(Get());
    return 0;
}

Iне знаю, почему он не войдет в конструктор перемещения.

Это действительно R-значение из Get ();

Если я изменил конструктор неконстантного копирования из конструктора const,

это войдет в конструктор перемещения.Поведение изменилось ...

Может ли кто-нибудь любезно объяснить, почему это произошло?

1 Ответ

1 голос
/ 14 марта 2012
#include <iostream>

using namespace std;

class Foo
{
public:
    Foo():
        Memory(nullptr)
    {
        cout<< this << "Foo Constructor"<<endl;
    }

    ~Foo()
    {
        cout<< this << "~Foo Destructor"<<endl;
        if(Memory != nullptr)
            delete []Memory;
    }

    Foo(Foo& rhs)
        :Memory(nullptr)
    {
        cout<<this << "Copy Constructor"<<endl;

        //allocate
        //this->Memory = new ....
        //copy 
        //memcpy(this->Memory, rhs.Memory...);
    }

    Foo& operator=(Foo& rhs)
    {
        cout<<"="<<endl;
    }
    void* Memory;

    Foo(int nBytes) { Memory = new char[nBytes]; }

    Foo(Foo&& rhs)
        {
        cout<<this << "Foo Move Constructor"<<endl;

                 Memory = rhs.Memory;


                 rhs.Memory = nullptr;
        }

};

Foo Get()
{
    Foo f;
    cout << &f << "f" <<endl;
    return f; 
}

void Set(Foo rhs)
{
    Foo obj(rhs);
    cout << &obj << "obj"<<endl;
}

int main()
{
    Set(Get());
    return 0;
}

output ...

0x7fffe38fa0a0 Foo Constructor
0x7fffe38fa0a0 f
0x7fffe38fa070 Copy Constructor
0x7fffe38fa070 obj
0x7fffe38fa070 ~Foo Destructor
0x7fffe38fa0a0 ~Foo Destructor

Ответ: Благодаря оптимизации именованного возвращаемого значения 1008 * параметр rhs создается на месте как псевдонимлокальная переменная f.(То есть rhs и f - это один и тот же экземпляр).

Поскольку rhs является lvalue, конструктор копирования используется для копирования конструкции obj из rhs.

...