클로져 객체의 복사 생성자와 소멸자 |
모든 클로져 객체들은 암묵적으로 정의된 복사 생성자(copy constructor)와 소멸자(destructor)를 가지고 있습니다. 이 때 클로져 객체가 복사 생성 될 때 값으로 Capture 된 것들의 복사 생성이 일어나겠지요. 아래의 예를 한번 보도록 하겠습니다.
일단
struct trace
{
trace() : i(0) { cout << "construct\n"; }
trace(trace const &) { cout << "copy construct\n"; }
~trace() { cout << "destroy\n"; }
trace& operator=(trace&) { cout << "assign\n"; return *this;}
int i;
};
와 같이 생성, 복사 생성, 소멸, 그리고 대입 연산을 확인할 수 있는 trace 라는 구조체를 정의해놓고
trace t;
int i = 8;
auto f = [=]() { return i / 2; };
를 한다면 어떻게 나올까요? f 에서 t 를 사용하지 않았으므로, t 를 Capture 하지 않게 됩니다. 따라서 그냥
이 나오게 됩니다.
그렇다면 아래의 예는 어떨까요
trace t;
int i = 8;
auto m1 = [=]() { int i = t.i; };
cout << " --- make copy --- " << endl;
auto m2 = m1;
먼저 m1 을 생성하면서, 람다가 t 를 Capture 하였으므로 t 의 복사 생성자가 호출되게 됩니다. 왜냐하면 값으로 받았기 때문이지요. 만일 레퍼런스로 받았다면 복사 생성자가 호출되지 않았을 것입니다 (확인해보세요!) 그리고 아래의 auto m2 = m1; 에서 클로져 객체의 복사 생성이 일어나는데, 이 때, 클로져 객체의 복사 생성자가 값으로 Capture 된 객체들을 똑같이 복사 생성 해주게 됩니다. 따라서 또 한번 t 의 복사 생성자가 호출되겠지요. 그 결과 아래와 같이 출력됩니다.
ref : http://itguru.tistory.com/196
'프로그래밍(Programming) > c++, 11, 14 , 17, 20' 카테고리의 다른 글
__attribute__ ((noinline)) (0) | 2017.05.14 |
---|---|
상속의 복사생성자 (0) | 2016.11.06 |
shared_ptr 순환 참조의 문제 weak_ptr (0) | 2016.07.17 |
가변 템플릿 typename... T (0) | 2016.07.07 |
연산자 오버로딩 함수를 상속 받는 방법 using (0) | 2016.07.04 |