Giới thiệu
Để biết tổng quan về kỹ thuật - bỏ qua câu trả lời này .
Đối với các trường hợp phổ biến khi xảy ra cuộc bầu cử sao chép - bỏ qua câu trả lời này .
Sao chép bản sao là một tối ưu hóa được thực hiện bởi hầu hết các trình biên dịch để ngăn chặn các bản sao bổ sung (có khả năng đắt tiền) trong các tình huống nhất định. Nó làm cho việc trả về theo giá trị hoặc thông qua giá trị khả thi trong thực tế (áp dụng các hạn chế).
Đây là hình thức tối ưu hóa duy nhất mà các elides (ha!) Quy tắc as-if - elision sao chép có thể được áp dụng ngay cả khi sao chép / di chuyển đối tượng có tác dụng phụ .
Ví dụ sau lấy từ Wikipedia :
struct C {
C() {}
C(const C&) { std::cout << "A copy was made.\n"; }
};
C f() {
return C();
}
int main() {
std::cout << "Hello World!\n";
C obj = f();
}
Tùy thuộc vào trình biên dịch & cài đặt, các đầu ra sau đây đều hợp lệ :
Chào thế giới!
Một bản sao đã được thực hiện.
Một bản sao đã được thực hiện.
Chào thế giới!
Một bản sao đã được thực hiện.
Chào thế giới!
Điều này cũng có nghĩa là có thể tạo ra ít đối tượng hơn, vì vậy bạn cũng không thể dựa vào một số hàm hủy cụ thể được gọi. Bạn không nên có logic quan trọng bên trong các công cụ sao chép / di chuyển hoặc hàm hủy, vì bạn không thể dựa vào chúng được gọi.
Nếu một lệnh gọi đến một bản sao hoặc di chuyển hàm tạo bị bỏ qua, hàm tạo đó vẫn phải tồn tại và phải có thể truy cập được. Điều này đảm bảo rằng việc sao chép sao chép không cho phép sao chép các đối tượng không thể sao chép thông thường, ví dụ: vì chúng có một công cụ xây dựng sao chép / di chuyển riêng tư hoặc bị xóa.
C ++ 17 : Kể từ C ++ 17, Copy Elision được đảm bảo khi một đối tượng được trả lại trực tiếp:
struct C {
C() {}
C(const C&) { std::cout << "A copy was made.\n"; }
};
C f() {
return C(); //Definitely performs copy elision
}
C g() {
C c;
return c; //Maybe performs copy elision
}
int main() {
std::cout << "Hello World!\n";
C obj = f(); //Copy constructor isn't called
}