← Back to C++ Course | Chapter 16: Modern C++ | Lesson 4 of 9

C++ में Move Semantics

Move semantics C++ को इन्हें copy करने की बजाय एक चीज़ के अंदरूनी हिस्से handover करने देता है, इसे duplicate करने की बजाय अपना पूरा box किसी को देने की तरह। बड़ी चीज़ों के लिए यह कहीं तेज़ है।
Syntax
cpp
data_type destination = std::move(source);  // transfers resources, source is left empty

Move Semantics क्या है?

Move semantics compiler को एक resource -- जैसे std::vector या std::string के अंदर heap-allocated memory -- का ownership एक temporary object से सीधे एक नए में transfer करने देता है, एक full deep copy perform करने की बजाय।

बड़े objects के लिए, यह एक O(n) copy को एक O(1) pointer swap में बदल देता है।

उदाहरण: What is Move Semantics?

cpp
// Include std::cout and std::cin
#include <iostream>
// Include std::vector
#include <vector>

// Program execution starts in main()
int main() {
	// Create a vector named source (a resizable array)
	std::vector<int> source = {1, 2, 3};
	// Create a vector named destination (a resizable array)
	std::vector<int> destination = std::move(source);
	// Print to the console with cout
	std::cout << destination.size() << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

std::move Function

std::move() खुद physically कोई data move नहीं करता -- यह purely एक cast है जो compiler को बताता है "इस lvalue को एक rvalue की तरह treat करो," इसे move-from होने के लिए eligible बनाते हुए।

Actual ownership transfer जो भी move constructor या move assignment operator बाद में इसे receive करता है उसके अंदर होता है।

उदाहरण: The std::move Function

cpp
// Include std::cout and std::cin
#include <iostream>
// Include std::string
#include <string>
#include <utility>

// Program execution starts in main()
int main() {
	std::string a = "Hello";
	// std::move transfers the resource instead of copying it
	std::string b = std::move(a);
	// Print to the console with cout
	std::cout << b << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Move Constructor

एक move constructor एक temporary object के internal resources (जैसे heap memory का एक raw pointer) का ownership उस pointer को नए object में copy करके लेता है, फिर temporary के अपने pointer को nullptr set करता है ताकि इसका destructor accidentally वह memory free न करे जिसका मालिक अब नया object है।

उदाहरण: Move Constructor

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the type Buffer
class Buffer {
// Members below can be accessed from outside the class
public:
	int *data;
	// Allocate an object on the heap with new
	Buffer(int val) { data = new int(val); }
	Buffer(Buffer &&other) noexcept {
		data = other.data;
		other.data = nullptr;
	}
	~Buffer() { delete data; }
};

// Program execution starts in main()
int main() {
	Buffer a(5);
	// std::move transfers the resource instead of copying it
	Buffer b(std::move(a));
	// Print to the console with cout
	std::cout << *b.data << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Move Assignment Operator

Move assignment operator पहले target object currently जो resources holds करता है उन्हें release करता है (एक leak से बचने के लिए), फिर same तरीके से source object के resources चुराता है जैसे एक move constructor करता है -- यही वजह है कि move assignment typically move constructor का logic reuse करने के लिए लिखा जाता है।

उदाहरण: Move Assignment Operator

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the type Buffer
class Buffer {
// Members below can be accessed from outside the class
public:
	int *data;
	// Allocate an object on the heap with new
	Buffer(int val) { data = new int(val); }
	Buffer &operator=(Buffer &&other) noexcept {
		// Free the heap memory with delete
		delete data;
		data = other.data;
		other.data = nullptr;
		// Send *this back to the caller
		return *this;
	}
	~Buffer() { delete data; }
};

// Program execution starts in main()
int main() {
	Buffer a(5), b(10);
	// std::move transfers the resource instead of copying it
	b = std::move(a);
	std::cout << *b.data << std::endl;
	return 0;
}

Performance Benefits

बड़े buffers रखने वाले types के लिए -- strings, vectors, और similar containers -- move semantics उस deep copy से बचता है जो वे types otherwise चाहते, जो सबसे ज़्यादा matter करता है जब functions से बड़े objects return करते हैं या उन्हें ऐसे containers में store करते हैं जो elements resize और relocate करते हैं।

उदाहरण: Performance Benefits

cpp
// Include std::cout and std::cin
#include <iostream>
// Include std::string
#include <string>

std::string buildGreeting() {
	std::string result = "Hello, World!";
	// Send result back to the caller
	return result;
}

// Program execution starts in main()
int main() {
	std::string message = buildGreeting();
	// Print to the console with cout
	std::cout << message << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. एक object को इससे move करने के बाद इस्तेमाल करना, जब इसकी value unspecified हो।
  2. move constructors पर noexcept भूल जाना, इसलिए containers move की बजाय copy कर सकते हैं।
  3. एक const object move करने की कोशिश करना, जो silently copy हो जाता है।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.