Game Develop

복사생성자는 언제 호출되는가? 본문

C++/GeeksForGeeks Quiz

복사생성자는 언제 호출되는가?

MaxLevel 2022. 7. 7. 03:35

복사생성자가 호출되는 경우를 고르는 문제이다.

이전문제와 같이 A,B,C,D가 전부 해당하기 때문에 정답은 E인 All of the above이다.

차례대로 보자면,

 

A. 클래스의 객체가 값으로 리턴될 때

B. 클래스의 객체가 함수에 매개변수로 넘겨질 때

C. 같은 클래스의 다른 객체를 기반으로 객체를 생성할 때

D. 컴파일러가 임시 객체를 생성할 때

E. 전부 다

 

A같은 경우, 함수 내에서 Temp a; return a; 라는 구문을 실행할 경우 a라는 인스턴스는 함수가 끝날 때 같이 소멸하지만, a를 리턴받는 곳에서 a의 값을 이용해 복사생성한 객체를 받기 때문에 복사생성자가 호출된다.

참고로 A의 경우처럼 객체를 값으로 리턴할 때 RVO,NRVO라는 컴파일러 최적화 기법?이 있다. 

 

일단 간단하게 말하자면 함수를 통해 객체를 리턴받는 과정에서의 불필요한 임시객체의 생성,소멸을 줄이는 컴파일러 최적화 기법이다. 이런게 있는것도 본 글을 작성하고 복사생성자에 관해 좀 더 알아보는 과정에서 우연히 알게 되었다.

다른분이 이해하기 편하게 정리한 글이 있어서 적어놓는다.

https://dydtjr1128.github.io/cpp/2019/08/10/Cpp-RVO(Return-Value-Optimization).html 

 

C++ RVO, NRVO에 대해서 알아보자. - dydtjr1128's Blog

Intro C/C++를 사용하는 이유 중 하나로는 빠른 속도와 커스터마이징 가능한 자언관리 등의 최적화를 위해서 사용할 것이다. 이러한 부분에서 코드를 개발하면서, 컴파일러...

dydtjr1128.github.io

 

그리고 단순히 함수에서 객체를 리턴할 때 뿐만 아니라, 함수에 매개변수로 넘길때도 마찬가지다.

아래 링크의 글도 한번 보면 도움된다.

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=jidon333&logNo=60211329854 

 

C++ : 임시 객체 전달과 컴파일러 최적화.

임시객체를 매개변수로 전달하는 여러 가지 경우에 대해서 생각해보다가 신기한 사실을 알게 되었다. 우선 ...

blog.naver.com

매개변수에 넘길때도 저런식으로 아예 임시객체를 넘겨버리면 컴파일러가 알아서 함수내부에 값을 넣어버려 바로 쓸 수 있게 해준다. 이것도 마찬가지로 릴리즈모드로 컴파일 할 때 NRVO가 적용되는지는 정확히 모르겠는데, 나중에 한번 실험해보고 결과를 추가해놓겠다.

 

글을 쓰다보니 퀴즈에 대한 글을 안쓰고 RVO,NRVO에 대한 내용이 많이 작성되었는데 사실 결국 A,B,C를 수행하면 D가 수행되기 때문에(컴파일러의 임시객체 생성) 당연히 전부다 맞는 말이다.

 

그리고 이건 내가 헷갈려서 적어놓는다.

첫번째 링크의 글에보면 

 auto foo = MakeFoo("foo1");

 

부분에서, MakeFoo("foo1")의 리턴값을 foo에 넣는과정에서는 복사생성자가 호출되지 않는다.

사실 원래 당연히 호출되는줄 알았다. 

Foo foo1;

Foo foo2 = foo1;

 

이렇게 하고 컴파일하면 복사생성자가 호출되기 때문이다. foo2를 foo1의 값들로 복사생성했기 때문이다.

그래서 당연히 위의 auto foo = MakeFoo("foo1"); 도 호출될 줄 알았는데.. 아마 이것도 결국 이미 만들어져있던 객체가 아닌 임시객체를 바로 대입하기 때문에 컴파일러가 따로 복사생성자를 호출하지 않는 것 같다.