Move Semantics
Bir objeden başka bir objeye kaynakların verimli bir şekilde aktarılmasını sağlar. Örneğin garajınızda bir arabanız var. Anahtarını arkadaşınıza verip “artık bu senin” diyorsunuz. Artık bir arabanız yok ve arabayı tekrardan kullanmak için arkadaşınızın anahtarı geri vermesi gerekli. Arabayı arkadaşınıza vermek için bir kopya oluşturmadınız onun yerine var olanı transfer ettiniz.
Value Semantics
Verileri transfer etmek için kopyalarsınız. Bu durum sizi bir garbage collector kullanmaktan kurtarır lakin verimi daha düşüktür. Bir fonksiyona bir argüman verdiğinizde default olarak kopyalama işlemi yapar.
Move işleminde eğer değişkeniniz rvalue ise kopyalanmak yerine transfer/move edilebilir.
Lvalues and Rvalues
Bir obje, lvalue veya rvalue olabilir. Klasik olarak bir lvalue atama operatörünün solunda ve bir rvalue atama operatörünün sağında bulunabilir.
x = 5; // x lvalue; 5 rvalue
y = f(); // y lvalue; f()'in dönüş değeri rvalueTabi bu tanım yeterince açık değil. C++’da lvalue, isimlendirilmiş bir bellek bölgesini ifade eder.
- İsmi olmalı
- & operatörü ile adresini alabilmeliyiz
Bunun dışında kalan her şey rvalue’dür yani:
- & ile adresi alınamaz
Fonksiyonlara atanırken farklı davranışlar gösterebilir. Bir lvalue
| Method | Lvalue | Rvalue |
|---|---|---|
| Pass by value | f(x) | f(5) |
| Pass by adress (pointer) | f(&x) | Yapamaz |
| Pass by reference | f(x) | Yapamaz |
| Pass by const reference | f(x) | f(5) |
- Pass by value’de değerler kopyalanıp öyle atanıyor dolayısıyla her ikisi için de sorun yok.
- Pass by adress’de ise belli bir bellek bölgesinin adresini göstermemiz gerekli Rvalue ile böyle bir şey yapamıyoruz
- Pass by reference’de de aynı durum geçerli.
- Pass by const reference’de ise bunun aksine Rvalue ile atama yapmak mümkün. Çünkü const olması bu değişkenin fonksiyon içinde değişmeyeceğini garanti eder. Bu sayede 5 sayısını fonksiyon içinde kullanabiliriz.
Pass by move
Lvalue and Rvalue References
Lvalue Reference
- Arka planda pointer olarak implemente edilebilir. [1]
- lvalue ‘ları referans edebilir
- const olduğunda rvalue ‘leri de referans edebilir.
int a = 5; // a is a lvalue
int& ra = a; // ra is a lvalue reference
int& rb = 5; // ERROR: A rvalue cannot bind to lvalue reference ...
const int& rc = 5; // ... unless it is constRvalue Reference
- Rvalue tutmak için rvalue reference kullanabiliriz.
- Rvalue reference, bir lvalue’dür !
int&& a = 5;
cout << a << endl; // 5
cout << &a << endl; // 0000007899CFFCB0
// 5 is a rvalue, a is a lvalue !!!
// even it is reference a rvalue
int lv = 5;
int&& b = lv; // ERROR: an rvalue reference cannot be bound to an lvalue
int&& b = std::move(lv); // but we can use std::move
cout << &b << endl; // 5
cout << &lv << endl; // 5std::move()
- gerçekte move etmez, rvalue’e cast eder.
- rvalue alan yerlere lvalue atmak için kullanılır
- lvalue’nun gözden çıkarılabilir olması gerekli çünkü tuttuğu data std::move() çalıştıktan sonra kullanılabilir olmayabilir.
| Method | Lvalue | Rvalue |
|---|---|---|
| Pass by value | f(x) | f(5) |
| Pass by adress (pointer) | f(&x) | Yapamaz |
| Pass by lvalue reference | f(x) | Yapamaz |
| Pass by const lvalue reference | f(x) | f(5) |
| Pass by rvalue reference | Yapamaz | f(5) |
Value Categories
- Literals
- ismi yoktur ve referans edilemezler
- pure rvalues veya prvalues olarak isimlendirilir
- Temporary objects
- Data’sı move edilebilir bir objeyi temsil eder
- xvalues olarak adlandırılır.
- lvalues

https://learn.microsoft.com/en-us/cpp/cpp/lvalues-and-rvalues-visual-cpp?view=msvc-170
https://stackoverflow.com/questions/3601602/what-are-rvalues-lvalues-xvalues-glvalues-and-prvalues
Move Operators
#include <iostream>
#include <string>
using namespace std;
class Text{
public:
// Constructors
Text(); // Default constructor
Text(const Text& other); // Copy constructor
Text(Text&& other) noexcept; // Move constructor
~Text(); // Destructor
// Assignment operators
Text& operator=(const Text& other); // Copy assignment
Text& operator=(Text&& other) noexcept; // Move assignment
private:
int size;
char* data;
};
// Default constructor
Text::Text() : size{}, data{} {}
// Copy constructor
Text::Text(const Text& other) : size(other.size), data(new char[other.size]){
std::copy(other.data, other.data + size, data);
}
// Move constructor
Text::Text(Text&& other) noexcept : size{}, data{}{
size = other.size;
data = other.data;
other.size = 0;
other.data = nullptr;
}
// Destructor
Text::~Text(){
delete[] data;
}
// Copy assignment
Text& Text::operator=(const Text& other){
if (this != &other) {
delete[] data;
size = other.size;
data = new char[size];
std::copy(other.data, other.data + size, data);
}
return *this;
}
// Move assignment
Text& Text::operator=(Text&& other) noexcept{
if (this != &other) {
delete[] data;
size = other.size;
data = other.data;
other.size = 0;
other.data = nullptr;
}
return *this;
}- move only
- copy only
- reference collapsing
- forwarding
Perfect Forwarding
Kaynaklar

Leave a Reply