2009-11-07 1 views
10

vector과 같은 STL 컨테이너는 객체를 추가 할 때 객체를 복사합니다. 나는 그것이 참조로 항목을 걸리는 것을보고 놀란다STL 컨테이너는 개체를 어떻게 복사합니까?

void push_back (const T& x); 

: 같은 push_back 방법이 보인다. 어떻게 작동하는지보기 위해 샘플 프로그램을 작성했습니다.

struct Foo 
{ 
    Foo() 
    { 
     std::cout << "Inside Foo constructor" << std::endl; 
    } 

    Foo(const Foo& f) 
    { 
     std::cout << "inside copy constructor" << std::endl; 
    } 
}; 

Foo f; 
std::vector<Foo> foos; 
foos.push_back(f); 

이 복사 객체를 그리고 그것이 복사 생성자를 호출 볼 수 있습니다.

제 질문은 push_back이 항목을 참조로 사용하는 경우 복사 생성자를 호출하는 방법입니다. 아니면 여기에 뭔가 빠졌나요?

모든 의견 ..?

답변

12

아마도 내부 배열에 개체를 내부적으로 구성하기 위해 "placement new"을 사용합니다. 게재 위치 new은 메모리를 할당하지 않습니다. 지정한 위치에 객체를 놓고 생성자를 호출합니다. 구문은 new (address) Class(constructor_arguments)입니다.

복사 생성자 T::T(T const &)이 호출되어 해당 위치에서 복사본을 만듭니다. 이런 식으로 뭔가 (간체) : T이 작동하지 복사 생성자가 있어야

template<T> 
void vector<T>::push_back(T const &item) { 
    // resize if necessary 
    new (&d_array[d_size++]) T(item); 
} 

참고. 기본적으로 (아무 것도하지 않으면) 무료로 제공됩니다. 명시 적으로 정의하는 경우 vector<T>을 사용하려면 public이어야합니다.

Here's how GNU's libstdc++ does it 그러나 나는 그것이 매우 계몽 적이라고 생각하지 않습니다. 할당 자 (vector의 두 x 째 템플리트 인수)는 덜 직관적입니다.

+0

T에 매개 변수없는 생성자가 있으면 정상입니다. 그러나 매개 변수화 된 생성자가있을 때 어떤 일이 발생합니까? 벡터가 새로운 객체를 초기화하는 방법은 무엇입니까? –

+0

T가 _copy 생성자 _을 가지고 있으면 괜찮습니다. 명시 적으로 "private"또는 "protected"가 아닌 한 기본적으로, 그리고 구현하면됩니다. – Thomas

+0

명확하게 대답을 편집했습니다. – Thomas

1

배치 new 연산자를 사용하여 단위화된 메모리에 복사 구성합니다.

새로운 배치는 메모리의 지정된 주소에 벡터 요소 인 현재 end()에 새 요소를 작성합니다. (대부분의 STL 구현 반대) 아주 명확한 코드가 http://spotep.com/dev/devector.h에서

void push_back(const T& val){ 
::new (&*end()) T(val); 
[increase end] 
} 

보세요.

3

효율성을 높이기 위해 C++ SDK는 항상 const T &을 함수 매개 변수로 사용합니다.

T을 매개 변수로 사용하는 경우 복사 작업은 두 번째로 수행되며 하나는 기능을 push_back(f)으로 전달하기위한 것이고 하나는 내부적으로 컨테이너에 추가하는 것입니다. 그리고 매개 변수로 const T&을 가져 가면 단 하나의 사본 만 필요합니다!

+7

C++ SDK가 없습니다. – GManNickG

+0

좋아요, C++ 언어 사양, STL 요법과 같은 뒷 배경을 의미합니다 ... – learner