■ Modern C++
C++11로 넘어오면서 auto, lambda, ravlue-ref(오른값 참조) 이 삼총사가 큰 변화이다. auto, lambda 같은 경우에는 없어도 우리가 기존에 하던 방식으로 잘 개발 할 수 있어 새로운 기능보단 편의성이 증대한 것인데
오른값 참조는 없던 개념이 새로 생긴거여서 이로 인해 C++자체가 업그레이드 되고 더 빨라졌다. 그래서 C++11에 새로 추가된 문법 중 우선순위 1이나 다름없다.
■ 왼값(l-value) vs 오른값(r-value)
(1) l-value : 단일식을 넘어 계속 지속되는 개체
(2) r-value : l-value가 아닌 나머지
기본적으로 오른쪽에 있으니 오른값이라고 생각할 수 있으나 정확히는 그것이 아니다.
■ 복사 생성자 vs 복사 대입 연산자
위 코드를 기준으로 호출한다면 아래와 같을 것이다.
(1) 복사 생성자
Knight k1;
Knight k2 = k1;
(2) 복사 대입 연산자
Knight k1;
Knight k2;
k2 = 1;
■ 복사, 왼값 참조
C#에선 클래스라면 참조 형태로 구조체라면 복사 형태로 알아서 넘겨줬었는데 C++에선 그렇지 않다.
첫번째 함수를 사용한다면 클래스여도 C++은 기본적으로 복사해서 파라미터를 넘겨주는 원리로 작동하기 때문에 복사가 발생한다.
만약 클래스의 복사 비용이 커질 것을 우려한다면 두번째와 같이 &참조 기호를 붙여 참조형태로 인자를 넘겨주는 방식을 택하면 되었다.
또한 세번째는 const를 붙여 원본을 넘겨주되 원본값을 수정하지 않겠다고 명시하는 것이다.
[요약]
(1) 첫번째 함수는 복사해서 복사본을 넘겨준다는 뜻.
(2) 두번째 함수는 원본을 넘겨줄테니 건드려도 된다는 뜻.
(3) 세번째 함수는 원본을 넘겨주지만 건드릴 수 없다는 뜻
위 세 가지 문법은 C++에서 기본적인 문법으로 착안되었다. 그리고 모던 C++이라고 할 수 있는 C++11부터는 오른값 참조가 추가되면서 이동 대입연산, 이동 생성자 등이 생겨나게되었다.
■ 오른값 참조
오른값 참조란 위와 같이 파라미터의 타입에 && 참조기호를 두 번 붙여주는 것이다.
추가로 noexcept 키워드를 붙여주곤 한다.
* noexcept 키워드 |
함수가 예외를 throw 하지 않을 것이라는 키워드. 이렇게 명시해놓으면 컴파일러가 해당 함수는 예외가 발생하지 않는다고 가정할 수 있어서 예외처리코드를 생성하지 않는다. 이는 프로그램의 성능을 향상 시켜준다. 하지만 남발하면 안되고 실제로 예외를 던지지 않음을 확신이 있을 때만 사용해야함. 왜냐하면 noexcept 함수 내에 예외가 발생한다면 'std::terminate()'이 호출되어 프로그램이 비정상적으로 종료된다. |
[그래서 이게 왜 필요하나?]
우리가 만약에 Knight 클래스 안에 Pet 클래스를 갖고있다고 하자.
만약에 기존의 방식 (복사 대입 or 복사 생성)을 적용한다면 Pet 클래스의 내용들을 전부 복사해줘야 하는 번거로움이 있다. 만약 pet클래스의 내용이 방대하다면 복사비용은 그 또한 비례할 것이고 이는 프로그램의 성능을 저하시켜버린다.
하지만 아래와 같이 이동 대입 연산자를 통해 '소유권'을 넘겨준다면 Pet클래스에 대한 복사비용이 일어나지 않는다.
[사용법]
그래서 기존 방식과 달리해야 하는 것은 아래와 같다.
k2 = k1;로 복사대입연산자를 실행했었으나
이동 대입 연산은 아래와 같이 오른값 참조를 적용해야 한다.
k2 = static_cast<Kngiht&&>(k1);
혹은
k2 = std::move(k1);
[적용 할 수 있는 예]
우리가 자료구조에서 '벡터'를 떠올리면 '이사비용'이 떠오를 것이다. 기존 원소들을 복사해서 이동시켜주는 것이 아니라 이동연산자를 통해서 옮겨주면 이사비용을 훨씬 아낄 수 있을 것이다.
실제로 직접 만들어본 벡터는 해당 지식이 없어서 복사 연산으로 이사를 진행했지만, 실제 원본에선 이동연산으로 되어있는 것을 확인할 수 있다.
'개발 (언어) > C++' 카테고리의 다른 글
[Modern C++] weak_ptr, unique_ptr (0) | 2024.03.31 |
---|---|
[Modern C++] shared_ptr (0) | 2024.03.31 |
[Modern C++] Unicode, MBCS, WBCS (1) | 2024.03.29 |
[Modern C++] String (0) | 2024.03.29 |
[C++] 동적 미로 생성, 우수법 탈출 AI (0) | 2024.03.24 |