-
[C++] 복사 생성자와 RVO, NRVOStudy/C & C++ 2022. 9. 19. 16:24
01. 복사 생성자란?
- 같은 타입의 인스턴스를 매개변수로 받는 생성자를 의미한다.
class A { public: A() {}; A(const A& a){}; // Copy Constructor };
02. 복사 생성자가 호출되는 경우
복사 생성자가 호출되는 경우는 세 가지이다.
- 기존 생성 객체를 사용해 새로운 객체를 초기화하는 경우
- Call-By-Value 형식으로 함수의 매개변수를 전달할 때
- Value 형태로 함수에서 return할 때
A origin; // 1. A copy(origin); A copy1 = origin; // 2. void Copy(A a) { // do something } // 3. A Copy2() { return A(); }
그렇다면, 아래 코드의 결과는 어떨까?
#include <iostream> class A { public: A() { std::cout << this << " Constructor Called\n"; } A(const A& a) { std::cout << this << " Copy Constructor Called\n"; } ~A() { std::cout << this << " Destructor Called\n"; } }; A Copy(A origin) { return A(origin); } int main() { A origin; A c1 = Copy(origin); }
위에서 말한 복사 생성자 호출 조건에 따르면 복사 생성자는 총 3번 불려야 한다.
- Copy() 함수의 매개변수 origin이 생성되며 한 번
- return값으로 전달되는 임시 객체를 생성하며 한 번
- c1의 복사 생성자가 호출되며 한 번
그러나 실제로 Visual Studio로 실행해보면 Copy Constructor는 두 번 호출된다. 이는 RVO라는 컴파일러 최적화 기법 때문이다.
RVO (Return Value Optimization)은 C++11부터 공식화된 기능으로, 불필요한 복사를 컴파일러가 최소화한다.
RVO가 적용되면 위 코드에서 복사 생성자가 호출되는 부분은 다음과 같다.
- Copy() 함수의 매개변수 origin이 생성되며 한 번
- return값으로 전달되는 임시 객체를 생성하며 한 번
c1은 리턴되는 임시 객체의 주소를 바로 참조하게 된다.
NRVO (Named Return Value Optimization)은 말 그대로 Named, 함수 스코프 안에서 이름이 있는 임시 객체가 반환될 때에도 최적화를 수행하는 것이다.
즉, 위의 Copy함수가 아래와 같은 형태더라도 최적화를 수행해준다.
A Copy(A origin) { A copy(origin); return copy; }
NRVO는 최적화 옵션 /O1부터 동작한다고 하는데... 잘 모르겠지만 비주얼 스튜디오 기준으로 Release모드에서 적용된다.
반환값 최적화 RVO, NRVO
클래스 내에서 어떤 객체를 반환하고 싶다. 하지만 반환되는 과정의 오버헤드가 두려울 수 있다. 1 2 3 4 std::string get_name() const { return std::string(my_name); } 일단 저 구문을 보면 이렇게..
zepeh.tistory.com
Rvalue 와 RVO, NRVO
C/C++를 써야만 하는 혹은 쓸 수 밖에 없는 상황들이라는 것은 대부분 성능,속도, 자원 사용의 최적화 등이지요. Visual Studio 2010에 새로이 추가된 Rvalue concept 이나 사용 예들도 정확히 이러한 상황
egloos.zum.com
'Study > C & C++' 카테고리의 다른 글
[C++] stringstream을 while문의 조건으로 사용할 때 주의할 점 (0) 2022.10.13 [따배씨++] 변수, 상수, 전처리기 등 정리 (0) 2022.09.16 [C] 버퍼(stdin)에 대한 이해와 scanf의 문제점 (0) 2022.09.14