이번 편의 목표: 문자열과 unique_ptr의 소유권을 복사 없이 옮기고, 짧은 계산을 람다로 적어 호출합니다.
복사는 같은 내용의 새 자원을 만듭니다. 이동은 이미 있는 자원의 소유권만 다른 객체로 옮깁니다. std::move는 이동을 수행하지 않습니다. 이 객체를 이동해도 된다는 타입 변환입니다. 실제로 자원을 옮기는 쪽은 이동 생성자와 이동 대입입니다.
#include <iostream>
#include <memory>
#include <string>
#include <utility>
struct Book {
std::string title;
};
int main() {
std::string source = "개미";
std::string moved = std::move(source);
source = "공책";
std::cout << moved << '\n';
std::cout << source << '\n';
auto original = std::make_unique<Book>();
original->title = "개미";
auto owner = std::move(original);
if (original == nullptr) {
std::cout << "원본 포인터는 비었습니다." << '\n';
}
std::cout << owner->title << '\n';
auto double_price = [](int price) { return price * 2; };
std::cout << double_price(1800) << '\n';
return 0;
}첫 두 줄의 출력은 개미와 공책입니다. 이동된 string은 유효한 객체로 남지만, 안의 문자열이 무엇인지 가정하지 않습니다. 다시 값을 넣은 뒤에만 내용을 출력합니다. unique_ptr은 이동 뒤 원본이 nullptr가 됩니다. 이 사실은 표준이 보장합니다.
람다는 그 자리에서 만드는 함수 객체입니다. double_price(1800)은 3600입니다. 람다가 바깥 변수를 써야 하면 대괄호 안에 캡처를 적습니다. 수명이 끝나는 지역 변수를 참조로 캡처해 밖에 들고 나가면, 그 참조를 쓰는 순간 의미가 정의되지 않습니다.
멤버가 string과 vector뿐인 클래스는 복사와 이동과 소멸을 컴파일러가 맞게 만듭니다. 직접 자원 포인터를 가진 클래스만 이 다섯 가지를 손수 정의하거나 삭제합니다. 21편의 File은 복사를 삭제해 그 경우에 해당합니다.
직접 해 보기
람다로 하루 100원과 일수를 곱하게 만들고 3일의 결과를 출력하세요. unique_ptr은 이동한 뒤 원본이 비어 있을 때만 새 소유자의 제목을 출력하세요.
해설
[](int days) { return days * 100; }에 3을 넘기면 300입니다. original == nullptr인 분기 안에서만 owner->title을 읽으면 소유자가 하나인 상태를 유지한 채 출력합니다.
COMMENTS
댓글 0
이 글에 대한 의견이나 질문을 남겨 주세요.
댓글은 구글이나 카카오로 시작한 뒤에 남길 수 있습니다.
등록된 댓글이 없습니다.