move semantics
Főnév
move semantics (tsz. move semanticses)
- (informatika) A C++ move szemantika a C++11-es szabvány egyik legfontosabb újítása, amely lehetővé teszi az erőforrások hatékony átvitelét az objektumok között, különösen nagy objektumok (pl. dinamikusan allokált tömbök, fájlkezelők, stb.) esetén. A mozgatás nem más, mint az erőforrás „ellopása” az egyik objektumtól, hogy a másik hatékonyan felhasználhassa azt, anélkül, hogy szükségtelen másolatokat kellene készíteni.
🔧 Miért van szükség move szemantikára?
Hagyományos másolás során az objektum összes erőforrását (pl. heap-en lévő memóriaterület) lemásoljuk. Ez költséges lehet:
std::vector<int> v1 = {1, 2, 3, 4, 5};
std::vector<int> v2 = v1; // másolat, az elemek is másolódnak
C++98-ben ez volt az egyetlen lehetőség. De mi van akkor, ha v1-et már nem akarjuk használni? Ekkor jön képbe a move konstruktor és move értékadó operátor.
📦 Lvalue vs Rvalue
- Lvalue: olyan objektum, aminek neve van és hivatkozható (pl.
a,vec,obj) - Rvalue: ideiglenes objektum (pl.
5,a + b,std::string("abc"))
int a = 5; // a: lvalue, 5: rvalue
std::string s = std::string("hello"); // jobb oldali std::string: rvalue
🏃♂️ std::move
A std::move() egy cast, amely egy lvalue-t rvalue-re castol, így mozgathatóvá válik.
std::string a = "alma";
std::string b = std::move(a); // b "ellopja" a tartalmát
Ez nem másolás, hanem áthelyezés. a érvényes, de meg nem határozott állapotban van.
✳️ Move konstruktor és értékadó operátor
class MyClass {
int* data;
size_t size;
public:
// Move konstruktor
MyClass(MyClass&& other) noexcept
: data(other.data), size(other.size) {
other.data = nullptr;
other.size = 0;
}
// Move értékadó operátor
MyClass& operator=(MyClass&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
size = other.size;
other.data = nullptr;
other.size = 0;
}
return *this;
}
// Destruktor
~MyClass() {
delete[] data;
}
// Konstruktor
MyClass(size_t s) : data(new int[s]), size(s) {}
};
🔄 Példa használat
MyClass a(1000); // nagy tömb
MyClass b = std::move(a); // nem másolat, hanem move!
a többé nem birtokolja az erőforrást, b viszont igen. Ez sokkal gyorsabb, mintha az egész data tartalom másolva lenne.
🧠 Használati esetek
1. Visszatérés függvényből:
std::vector<int> create_vector() {
std::vector<int> vec = {1, 2, 3, 4};
return vec; // C++11-től ez mozgás (return value optimization - RVO)
}
2. Konténer feltöltés:
std::vector<std::string> v;
std::string name = "ChatGPT";
v.push_back(std::move(name)); // nem másol, hanem move-ol
📛 Mikor ne használd?
- Ha az objektumra még szükséged van
- Ha az objektum move konstruktorát nem implementáltad helyesen
- Ha a mozgás után az eredeti objektumot használnád, de az már „üres” vagy érvénytelen
❗ Rule of Five
Ha egy osztály:
- dinamikus memóriát vagy más erőforrást kezel (pl. fájl, mutex, stb.)
Akkor implementálni kell:
- Másoló konstruktor
- Másoló értékadó operátor
- Destruktor
- Move konstruktor
- Move értékadó operátor
class MyClass {
// rule of five megvalósítás itt
};
🤖 Mit csinál az STL?
Az STL konténerek (pl. std::vector, std::map) teljes mértékben támogatják a move szemantikát. Ha az elemek move-képesek, akkor a konténerek is gyorsabbak lesznek.
std::vector<std::string> v;
v.push_back(std::move(myStr)); // move konstruktor hívódik meg
🧪 Ellenőrzés std::is_move_constructible
#include <type_traits>
std::is_move_constructible<MyClass>::value; // true vagy false
Ez megmondja, hogy egy típus mozgatható-e.
🔍 Move-only típus
Olyan osztály, amely csak mozgatható, de nem másolható:
class Unique {
std::unique_ptr<int> ptr;
public:
Unique(std::unique_ptr<int> p) : ptr(std::move(p)) {}
Unique(const Unique&) = delete;
Unique& operator=(const Unique&) = delete;
Unique(Unique&&) = default;
Unique& operator=(Unique&&) = default;
};
Ilyen pl. std::unique_ptr maga is.
✅ Összefoglalás
| Fogalom | Jelentés |
|---|---|
std::move |
Lvalue-t rvalue-vé alakít |
| Move konstruktor | Erőforrásokat „ellopó” konstruktor |
| Move értékadó operátor | Mozgatás értékadáskor |
| RVO / NRVO | Return Value Optimization (másolás elkerülése) |
| Rule of Five | 5 alapvető metódus, ha erőforrásokat kezelünk |
| Move-only típus | Nem másolható, csak mozgatható objektum |
- move semantics - Szótár.net (en-hu)
- move semantics - Sztaki (en-hu)
- move semantics - Merriam–Webster
- move semantics - Cambridge
- move semantics - WordNet
- move semantics - Яндекс (en-ru)
- move semantics - Google (en-hu)
- move semantics - Wikidata
- move semantics - Wikipédia (angol)