Move Semantics
Copy constructor/assignment poore data ki duplicate copy banate hain — bade objects (jaise ek million-element vector) ke liye ye expensive hai. Move semantics (C++11+) se "ownership transfer" kar sakte ho — data physically copy kiye bina, sirf pointers/resources ka ownership source se destination mein move ho jaata hai.
std::move() khud kuch move nahi karta — ye sirf object ko "rvalue" (movable) mark karta hai, compiler ko batata hai "iski value ab chahiye nahi, ise move kar sakte ho." Move constructor/assignment phir actual efficient transfer karte hain.
#include <vector>
#include <utility>
using namespace std;
int main() {
vector<int> source = {1, 2, 3, 4, 5};
vector<int> copied = source; // COPY — poora data duplicate hota hai
vector<int> moved = move(source); // MOVE — ownership transfer, data copy nahi
cout << moved.size() << endl; // 5
cout << source.size() << endl; // 0 — source ab empty hai (moved-from state)
return 0;
}- Move = ownership transfer, data physically copy nahi hota
- std::move() sirf "ise move kiya ja sakta hai" mark karta hai
- Bade objects (vectors, strings) ke liye bahut zyada performance fayda
Apni custom classes ke liye bhi move constructor/assignment likh sakte ho (&&, rvalue reference syntax se) — resource ko efficiently "steal" karte hain source object se, aur source ko empty/valid state mein chhod dete hain.
class Buffer {
int *data;
int size;
public:
Buffer(int s) : size(s) { data = new int[size]; }
// Move constructor:
Buffer(Buffer &&other) noexcept : data(other.data), size(other.size) {
other.data = nullptr; // source ko empty chhodo
other.size = 0;
}
~Buffer() { delete[] data; }
};
int main() {
Buffer b1(100);
Buffer b2 = move(b1); // move constructor chalega — data copy nahi hua, transfer hua
return 0;
}&& (rvalue reference) ek temporary/movable value ko refer karta hai — normal reference (&) ek existing, named variable ko refer karta hai (lvalue). Move constructor Type&& parameter leta hai kyunki wo sirf temporaries (ya std::move() se explicitly marked values) accept karta hai.
void process(int &x) { cout << "lvalue reference" << endl; }
void process(int &&x) { cout << "rvalue reference" << endl; }
int main() {
int a = 5;
process(a); // "lvalue reference" — a ek named variable hai
process(10); // "rvalue reference" — 10 ek temporary hai
process(move(a)); // "rvalue reference" — move() se explicitly marked
return 0;
}