일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- implicit conversion
- virtual function
- reference
- 루아
- 게임
- 반복자
- 오블완
- resource management class
- 언리얼
- 비교 함수 객체
- operator new
- 상속
- c++
- 참조자
- 영화 리뷰
- lua
- exception
- Smart Pointer
- 스마트 포인터
- 예외
- Vector
- more effective c++
- 다형성
- UE4
- 영화
- 암시적 변환
- 메타테이블
- effective stl
- 티스토리챌린지
- Effective c++
Archives
- Today
- Total
스토리텔링 개발자
[Effective STL] 3. 컨테이너 요소 복사 본문
728x90
항목 3. 복사(Copy)는 컨테이너 안의 객체에 맞게 비용을 최소화하며, 동작은 정확하게 하자
컨테이너의 요소
- 기본적으로 STL 컨테이너는 삽입, 삭제 시 복사 처리를 한다.
- 컨테이너가 가진 객체는 넣을 당시의 것과 같은 것이 아니다.
- 컨테이너에서 객체를 가져와도, 컨테이너에 있었던 것이 아니다.
- 컨테이너 내부의 객체조차도 늘 같은 것이라 보장할 수 없다.
- vector 등에 insert를 통해 데이터를 삽입하거나, erase로 지우거나 하는 경우.
- 컨테이너의 객체들은 복사를 통해 밀려나고 밀려온다.(항목 5, 항목 14 참조)
- 정렬 알고리즘이나 그와 비슷한 매커니즘의 함수를 호출하는 경우.
- next_permutation, previous_permutation, remove, unique / rotate, reverse 등.(항목 32 참조)
- vector 등에 insert를 통해 데이터를 삽입하거나, erase로 지우거나 하는 경우.
컨테이너 요소 복사
- 요소 객체의 복사 기능을 사용한다.
- 즉, 복사 생성자, 복사 대입 연산자를 사용한다.
class Widget
{
public:
Widget(const Widget&); // 복사 생성자
Widget& operator=(const Widget&); // 복사 대입 연산자
...
};
- 자동으로 만들어지는 복사 생성자, 대입 연산자는 얕은 복사를 한다.(Effective C++ 항목 11, 항목 27)
STL 복사로 인한 문제들
- 복사에 드는 비용이 큰 객체를 컨테이너에 넣는다면
- 수행 성능의 병목현상을 일으킬 수 있다.
- 커스텀 객체의 복사 동작이 단순히 복사 뿐 아니라 다양한 기능을 포함한다면
- 사이드 이펙트 문제도 있을 수 있다.(항목 8 참조)
- 상속된 객체를 컨테이너에 넣으려 한다면
- 삽입 중 객체 복사를 하다가 슬라이스 문제(object slicing)가 발생한다.(항목 22, 38 참조)
-
class SpecialWidget : public Widget { ... }; vector<Widget> vw; // 부모 클래스의 객체를 요소로 사용한다. SpecialWidget sw; vw.push_back(sw); // 자식 클래스 인스턴스를 카피하며 슬라이싱이 발생한다.
복사를 고려한 STL 사용법
- 객체에 대한 컨테이너가 아니라 포인터에 대한 컨테이너를 사용하도록 하자.
- 포인터의 장점
- 속도가 빠르다.
- 복사 시 정확히 동작한다.
- 슬라이스 문제가 발생하지 않는다.
- 포인터의 단점
- 메모리 해제가 필요하다.
- 물론 이는 스마트 포인터로 해결 가능하다.(항목 7, 33 참조)
STL은 불필요한 복사 생성을 피하도록 설계되어 있다.
- 기본 배열과 vector의 비교
Widget w[maxNumWidgets]; // 기본 배열
// maxNumWidgets 개의 배열 공간을 미리 할당해둔다.
// 즉, 선언과 동시에 기본 Widget 객체들이 maxNumWidgets개 생성된다.
vector<Widget> vw; // vector
// 지금 당장은 Widget 객체를 하나도 가지지 않는다.
// 필요할 때 메모리 공간이 자라난다.
// 필요하다면 공간을 예약할 수 있지만..
vw.reserve(maxNumWidgets); // 항목 14 참조
// 생성자가 불리진 않는다.
- 즉, 복사를 많이 하긴 하지만, 기본 배열보다는 훨씬 효율적이다.
728x90
'개발 > Effective STL' 카테고리의 다른 글
[Effective STL] 6. 컴파일러의 분석 오류 (0) | 2024.11.08 |
---|---|
[Effective STL] 5. 범위 멤버 함수(Range Member Function) (0) | 2024.11.07 |
[Effective STL] 4. 빈 컨테이너인지 확인하기 (0) | 2024.11.04 |
[Effective STL] 2. 컨테이너 독립성(Container-Independent) (2) | 2024.10.30 |
[Effective STL] 1. 컨테이너(Container) (0) | 2024.10.29 |
Comments