david's daily developer note

[C,C++] emplace_back 본문

[Develop] Native/C++ , C

[C,C++] emplace_back

mouse-david 2018. 5. 28. 17:14
728x90

이 글에서는 STL의 컨테이너의 emplace_back() 함수를 알아보려 한다.

정확하게는 이동생성자가 선언된 클래스에서 복사생성자가 무시되는지를 확인해보려고 한다.

emplace_back 함수와 push_back함수 호출로 이동/복사 생성자 동작을 확인해보자. (C++11, VS 2012).

class test_copy
{
public:
    test_copy() {}
    test_copy(int n) {}
    ~test_copy() { cout << "test_copy destructor" << endl; }
    test_copy(const test_copy& rhs) { cout << "test_copy : copy constructor" << endl; }
};

 

test_copy 클래스는 이동생성자가 없고, 복사생성자를 명시하였다.

(명시안하면 기본 복사생성자가 만들어지겠지만, 호출될 때, Copy라고 찍고싶었다..)

class test_move
{
public:
    test_move() {}
    test_move(int n) {}
    ~test_move() { cout << "test_move destructor" << endl; }
    test_move(const test_move& rhs) { cout << "test_move : copy constructor" << endl; }
    test_move(test_move&& rhs) { cout << "test_move : move constructor" << endl; }
};

 

test_move 클래스는 명시된 복사생성자가 있고, 이동생성자도 함께 명시하였다.

그리고 다음의 예제를 실험하였다.

int main () {
    std::vector < test_copy> test_copy_vec;
	test_copy_vec.push_back(test_copy());
	std::vector < test_move> test_move_vec;
	test_move_vec.push_back(test_move());
    ...
}

 

결과

1 : 생성->복사생성->소멸

2 : 생성->이동생성->소멸

 

예상대로, 이동생성자가 선언되면 복사생성자는 무시되었다.

(이동생성자/이동대입 연산자가 명시되어 있으면 복사생성자/복사대입 연사자는 삭제된다.)

이제 설레는 마음으로 emplace_back예제를 실행하였다.

int main()
{
	std::vector < test_copy> test_copy_vec;
	test_copy_vec.emplace_back(test_copy());
	std::vector < test_move> test_move_vec;
	test_move_vec.emplace_back(test_move());
	...
}

결과

 

1 : 생성->복사생성->소멸

2 : 생성->이동생성->소멸

 

둘의 결과는 같다.복사생성자와 이동생성자의 호출이 분기되었고, 각 장점을 취하였지만,

여전히, 결과의 생성과 소멸의 수는 같다(인자로 넣은 무명클래스의 생성,소멸).

STL컨테이너 함수는 가변인자 템플릿(Variadic Template) 개념을 사용하여서 무명클래스를 선언하지 않아도 된다.

차이를 확인하고자 가변인자 매개변수를 사용해보자.

int main() {
	std::vector < test_move> test_move_vec_1;
	test_move_vec_1.push_back(1);
	std::vector < test_move> test_move_vec_2;
	test_move_vec_2.emplace_back(2);
    ...
}

 

결과

1 : 생성->이동생성->소멸

2 : 생성

 

여기서 두 함수의 차이를 확인할 수 있다.

push_back은 컨테이너에 추가할 객체를 받아서 추가함으로 객체의 생성이 필요하다는 것, 

emplace_back함수는 가변인자 템플릿을 통하여 인자를 취하고 내부에서 필요한 시점에 직접 생성을 한다는것

앞의 예제1,2에서는 무명클래스로 객체를 생성했음으로, 동일한 결과를 만들었지만,

예제 3에서는 가변인자 템플릿으로 넘어가서, push_back은 객체를 한번 생성,

emplace_back은 내부에서 직접 생성함으로 결과가 달라진다.

 

객체의 생성,소멸 한단계가 뭐가 그렇게 중요할까 하지만,, 

 

C++이 점점..Managed의 서비스 생산성을 따라가기 힘들고,, (누가 개발하느냐에 따라 결과는 다르지만!!!)

그나마, 거대한 인프라도, 점점.. 밀리는 것 같은 상황에서...

우리가 실무에서 C++을 버리지 않는 이유는...

뒤집기 귀찮아서도 있지만...절대 불변.. 성능이때문일것이다..

이런 관점에서 객체의 생성,소멸 한단계가 줄어든다는데!!

너무 사랑스러운 개념이 아닌가..

 

이상 정말정말 간단하게.. emplace_back를 알아보았다

728x90

'[Develop] Native > C++ , C' 카테고리의 다른 글

[C,C++] memory fragmentation  (0) 2018.05.29
[C,C++] STL Container Reserve  (0) 2018.05.28
[C,C++] lvalue, rvalue  (0) 2018.05.25
[C,C++] Variadic Template  (0) 2018.05.17
[C,C++] 실행파일이 만들어지는 단계  (0) 2018.05.17