1. "Nedir?"
std::move()
Teknik olarak bir işlev olsa da - gerçekten bir işlev olmadığını söyleyebilirim . Bu , derleyicinin bir ifadenin değerini dikkate alma yolları arasında bir dönüştürücüdür .
2. "Ne işe yarar?"
Dikkat edilmesi gereken ilk şey, std::move()
aslında hiçbir şeyi hareket ettirmemesi . Bir ifadeyi lvalue (adlandırılmış değişken gibi) olmak yerine xvalue olmaya dönüştürür . Bir xvalue derleyiciye şunu söyler:
Beni yağmalayabilir, tuttuğum her şeyi taşıyabilir ve başka bir yerde kullanabilirsiniz (çünkü yakında yok olacağım).
başka bir deyişle, kullandığınızda std::move(x)
, derleyicinin yamyamlaşmasına izin veriyorsunuz x
. Böylece x
, örneğin, bellekte kendi arabelleği varsa - std::move()
derleyiciyi girdikten sonra bunun yerine başka bir nesne olabilir.
Ayrıca bir ön değerden (geçici olarak geçtiğiniz gibi) hareket edebilirsiniz , ancak bu nadiren yararlıdır.
3. "Ne zaman kullanılmalı?"
Bu soruyu sormanın bir başka yolu da "Mevcut bir nesnenin kaynaklarını ne için yamyam olurum?" uygulama kodu yazıyorsanız, derleyici tarafından oluşturulan geçici nesnelerle çok fazla uğraşmayacaksınızdır. Yani esas olarak bunu yapıcılar, operatör yöntemleri, standart-kütüphane-algoritma benzeri fonksiyonlar gibi yerlerde nesnelerin otomatik olarak çok fazla yaratıldığı ve imha edildiği yerlerde yapardınız. Tabii ki, bu sadece bir kural.
Tipik bir kullanım, kopyalamak yerine kaynakları bir nesneden diğerine 'taşımaktır'. @Guillaume , kısa bir örneği olan bu sayfaya bağlantı veriyor : iki nesneyi daha az kopyalamayla değiştirmek.
template <class T>
swap(T& a, T& b) {
T tmp(a); // we now have two copies of a
a = b; // we now have two copies of b (+ discarded a copy of a)
b = tmp; // we now have two copies of tmp (+ discarded a copy of b)
}
move komutunu kullanmak, kaynakları kopyalamak yerine değiştirmenize olanak tanır:
template <class T>
swap(T& a, T& b) {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
Ne olur düşünün T
, diyelim ki, bir vector<int>
n büyüklüğünde. İlk versiyonda 3 * n elemanını okuyup yazıyorsunuz, ikinci versiyonda temelde vektörlerin tamponlarına artı 3 tamponun boyutlarına sadece 3 işaretçi okuyup yazıyorsunuz. Tabii ki, sınıfın T
nasıl hareket edileceğini bilmesi gerekir; bunun için sınıfınızda bir hareket atama işleci ve sınıf T
için bir hareket oluşturucu bulunmalıdır.