Middle+
Hərəkət semantikası nədir və onu necə istifadə etmək olar?
sobes.tech Süni İntellekt
AI-dan cavab
Hərəkət semantikasını (move semantics) C++11 və yuxarı versiyalarda effektiv resursların idarə olunması üçün imkan verir, bu da lazımsız kopyalamadan qaçmağa kömək edir. Bu, rvalue istinadları (&&) və std::move operatorundan istifadə etməklə həyata keçirilir.
Əsas aspektlər:
- rvalue istinadları (
&&): Müvəqqəti obyektlərə (yəni, rvalues) və ya köçürülə bilən obyektlərə istinadlar. Tezliklə məhv ediləcək obyektə bağlanmağa imkan verir. std::moveoperatoru: Lvalue-i rvalue istinadına çevirir. Öz-özlüyündə köçürmə əməliyyatı etmir, sadəcə kompilyatora obyektin təhlükəsiz şəkildə köçürülə biləcəyini bildirir.- Köçürmə konstrukturu: rvalue istinadını arqument kimi qəbul edən xüsusi konstruktur. O, resursları (məsələn, dinamik yaddaş göstəriciləri) mənbə obyektindən oğurlayır və onu etibarlı, lakin boş vəziyyətə salır.
- Köçürmə ilə təyin operatoru: Köçürmə konstrukturu kimi, təyin əməliyyatları üçün nəzərdə tutulub.
İstifadə:
- Təkmilləşdirmə: Böyük obyektlərin və ya resurslara sahib obyektlərin (məsələn, konteynerlər, sətirlər, ağıllı göstəricilər) kopyalanma xərclərini azaldır.
- Effektiv konteynerlərin tətbiqi:
std::vectorkimi konteynerlərin ölçüsünü dəyişərkən və ya köçürərkən effektiv idarə etməyə imkan verir. - Böyük obyektlərin dəyər kimi geri qaytarılması: Kompilyator avtomatik olaraq köçürmə tətbiq edə bilər (return value optimization, RVO və ya Named Return Values Optimization, NRVO), əgər geri qaytarılan obyekt yerli dəyişən və ya müvəqqəti obyekt olarsa.
Nümunə:
#include <iostream>
#include <vector>
#include <string>
#include <utility> // std::move üçün
class MyResource {
public:
std::vector<int> data;
// Konstruktor
MyResource(size_t size) : data(size) {
std::cout << "Konstruktor" << std::endl;
}
// Destructor
~MyResource() {
std::cout << "Destructor" << std::endl;
}
// Köçürmə konstrukturu
MyResource(MyResource&& other) noexcept : data(std::move(other.data)) {
std::cout << "Köçürmə konstrukturu" << std::endl;
}
// Köçürmə operatoru
MyResource& operator=(MyResource&& other) noexcept {
if (this != &other) {
data = std::move(other.data);
}
std::cout << "Köçürmə operatoru" << std::endl;
return *this;
}
};
int main() {
MyResource res1(10); // Konstruktor
std::cout << "---" << std::endl;
MyResource res2 = res1; // Kopyalama konstrukturu və ya kopyalama operatoru, əgər res2 artıq mövcuddursa
std::cout << "---" << std::endl;
MyResource res3 = std::move(res1); // Köçürmə konstrukturu
std::cout << "---" << std::endl;
MyResource res4(5); // Konstruktor
res4 = std::move(res3); // Köçürmə operatoru
std::cout << "---" << std::endl;
return 0;
}
Bu nümunədə, std::move istifadə edilərək, köçürmə konstrukturu və ya köçürmə operatoru çağırılır, bu da data vektorunun məzmununun bahalı kopyalanmasının qarşısını alır.