2011-09-11 3 views
17

std::vector에 새 객체 요소를 푸시하는 올바른 방법은 무엇입니까? 벡터에 데이터를 할당하고 싶습니다. 이 코드는 객체에 벡터 newradio을 복사 한 다음 범위 밖으로 벗어날 때 newradio을 제거합니까 (예 : 스택 외부)?C++ 벡터 push_back

vector<Radio> m_radios; 
Radio newradio(radioNum); 
m_radios.push_back(newradio); 

그리고 내가 m_radios를 포함하는 객체, 벡터에 의해이 무료 모든 메모리 할당됩니다를 해제 할 때?

답변

29

std::vector은 자체 메모리를 관리합니다. 즉, 벡터의 소멸자가 호출 될 때 벡터에 의해 보유 된 메모리가 해제됩니다. std::vector은 또한 객체의 소멸자가 제거 될 때 (erase, pop_back, clear 또는 벡터의 소멸자를 통해) 호출합니다.

이 할 때 :

Radio newradio(radioNum); 
m_radios.push_back(newradio); 

당신은 벡터에 (들 복사 Radio '생성자를 사용하여 만든) newradio의 사본을 추가합니다. newradio은 범위를 벗어나면 파괴되며 벡터가 벡터에서 제거되면 복사본이 삭제됩니다 (모든 객체와 마찬가지로). 중요한 점이다

: std::vector에만 저장 사본 의미 복사 생성자가 있어야합니다 물체 의미 객체의 (및 할당 연산자를하지만 그건 또 다른 문제이다). 벡터의 포인터가 있다면 포인터 자체가 아닌 포인터 자체가 복사됩니다. 이 동작은 모든 표준 컨테이너 (예 : std::list 또는 std::set)와 동일합니다.

포인터를 사용하지 않는 경우 경험적으로 말하면 메모리를 직접 해제 할 필요가 없습니다. (vector 포함)에서는 C++ 11

대부분의 표준 컨테이너는 컨테이너의 끝에 곳에서 객체를 구축합니다 emplace_back 방법이있다. 많은 매개 변수가 필요하며 해당 매개 변수와 가장 잘 일치하는 생성자를 호출합니다 (또는 그러한 생성자가 없으면 실패합니다). 생성자를 사용하여 컨테이너의 끝에 복사하지 않고 개체를 만듭니다.

는 C++ 11에서 또한
m_radios.emplace_back(radioNum); // construct a Radio in place, 
           // passing radioNum as the constructor argument 

, 용기가 일반적으로 알고 이동 , 그래서 더 이상 복사 가능한 것으로 객체를 필요로하지 않는다 : 그래서, 위의 코드는 다음과 같이 다시 작성할 수 있습니다 그들은 이동를하는 경우, 다음 컨테이너는 필요에 따라 (예 : 재 할당 중에) 내용을 이동합니다. 벡터를 복사하려면 복사 가능 유형이 필요합니다.

+3

때 올바른 비록,이 대답은 업데이 트 언급을 사용할 수는' –

+0

아주 좋은 지적 씨 오리를 emplace_back'. –

0

예 : radioNum : m_radios으로 복사됩니다. newradio.~Radio(); (범위를 벗어났습니다.)이 발생했을 때 포인터를 할당 해제하지 않는 한 괜찮습니다. m_radios 또는 하위 클래스에서 포인터를 사용하는 경우 smart pointers (shared_ptr)으로 전환해야합니다.

m_radios이 범위를 벗어나면 소멸자가 자동으로 호출되고 모든 항목 std::vector이 해제됩니다.

1

예 newRadio를 밀면 Radio 객체의 복사본이 벡터로 푸시됩니다. 로컬에만 있기 때문에 벡터를 비울 필요가 없습니다. 범위를 벗어나면 소멸됩니다. 예를 들어 쓴 경우

vector<Radio> *m_radios = new vector<Radio>(); 

그런 다음 벡터 소멸자를 수동으로 호출하여 메모리를 확보해야합니다.

3

push_back()은 벡터 내에 인수의 복사본을 저장합니다. Radio이 적절한 값 의미를 구현하는 한 아무 문제가 없습니다.

0

복사 생성자에 대한 호출을 통해 push_back을 사용할 때 개체가 컨테이너에 복사되는지 확인하는 다른 답변 외에도 c++0x이 추가 된 새로운 emplace_back 기능을 염두에 두어야 할 수도 있습니다.

emplace_back을 호출하면 임시 개체를 생성하지 않고 해당 개체를 컨테이너 내부에서 직접 구성 할 수 있습니다. emplace_back는이 경우에, 당신은 개체의 생성자에 전달할 것 매개 변수를 받아들이는 varardic 템플릿 함수입니다 :

std::vector<Radio> m_radios; 
m_radios.emplace_back(radioNum); 

는 중간 임시직을 만들지 않습니다. 복사하는 데 비용이 많이 드는 경우에 유용 할 수 있습니다.

희망이 도움이됩니다.

0

기본적으로 std :: vector는 기본 클래스의 복사 생성자를 사용하여 메모리 자체를 관리합니다. 따라서 벡터 요소가 로컬 변수 인 것처럼 동작합니다 (벡터가 범위를 벗어나면 요소가 소멸됩니다).

이 동작을 원하지 않으면 대신 pointer 또는 boost :: ptr_vector의 벡터를 사용할 수 있습니다.

1

이 시도 :

#include<iostream.h> 
#include<vector.h> 

class base 
{ 
int i; 
public: 

    base(int z=0){i=z;cout<<"okk constructor "<<i<<" called\n";} 
    base(const base& b1){i=b1.i;cout<<"copy constructor "<<i<<" called\n";} 
    void display(){cout<<" val is "<<i<<" \n";} 
    ~base(){cout<<"destructor of "<<i<<" base called\n";} 
}; 


    int main() 
    { 
     cout<<"before anything\n"; 
     vector<base> basev; 
     base baseobj1(1); 
     base baseobj2(2); 
     base baseobj3(3); 
     base baseobj4(4); 
     base baseobj5(5); 
     base baseobj6(6); 
     base baseobj7(7); 
     base baseobj8(8); 
     base baseobj9(9); 
     base baseobj10(10); 


     basev.push_back(baseobj1); 
     cout<<"second push back\n"; 
     basev.push_back(baseobj2); 
     cout<<"third push back\n"; 
     basev.push_back(baseobj3); 
     cout<<"fourth push back\n"; 
     basev.push_back(baseobj4); 
     cout<<"fifth push back\n"; 
     basev.push_back(baseobj5); 
     cout<<"sixth push back\n"; 
     basev.push_back(baseobj6); 
     cout<<"seventh push back\n"; 
     basev.push_back(baseobj7); 
     cout<<"eighth push back\n"; 
     basev.push_back(baseobj8); 
     cout<<"ninth push back\n"; 
     basev.push_back(baseobj9); 
     cout<<"10th push back\n"; 
     basev.push_back(baseobj10); 
     cout<<"after all push back\n"; 


     cout<<"before clear\n"; 
     basev.clear(); 
     cout<<"after clear\n"; 


} 

출력 :

before anything 
okk constructor 1 called 
okk constructor 2 called 
okk constructor 3 called 
okk constructor 4 called 
okk constructor 5 called 
okk constructor 6 called 
okk constructor 7 called 
okk constructor 8 called 
okk constructor 9 called 
okk constructor 10 called 
copy constructor 1 called 
second push back 
copy constructor 1 called 
copy constructor 2 called 
destructor of 1 base called 
third push back 
copy constructor 1 called 
copy constructor 2 called 
copy constructor 3 called 
destructor of 1 base called 
destructor of 2 base called 
fourth push back 
copy constructor 4 called 
fifth push back 
copy constructor 1 called 
copy constructor 2 called 
copy constructor 3 called 
copy constructor 4 called 
copy constructor 5 called 
destructor of 1 base called 
destructor of 2 base called 
destructor of 3 base called 
destructor of 4 base called 
sixth push back 
copy constructor 6 called 
seventh push back 
copy constructor 7 called 
eighth push back 
copy constructor 8 called 
ninth push back 
copy constructor 1 called 
copy constructor 2 called 
copy constructor 3 called 
copy constructor 4 called 
copy constructor 5 called 
copy constructor 6 called 
copy constructor 7 called 
copy constructor 8 called 
copy constructor 9 called 
destructor of 1 base called 
destructor of 2 base called 
destructor of 3 base called 
destructor of 4 base called 
destructor of 5 base called 
destructor of 6 base called 
destructor of 7 base called 
destructor of 8 base called 
10th push back 
copy constructor 10 called 
after all push back 
before clear 
destructor of 1 base called 
destructor of 2 base called 
destructor of 3 base called 
destructor of 4 base called 
destructor of 5 base called 
destructor of 6 base called 
destructor of 7 base called 
destructor of 8 base called 
destructor of 9 base called 
destructor of 10 base called 
after clear 
destructor of 10 base called 
destructor of 9 base called 
destructor of 8 base called 
destructor of 7 base called 
destructor of 6 base called 
destructor of 5 base called 
destructor of 4 base called 
destructor of 3 base called 
destructor of 2 base called 
destructor of 1 base called 
+2

답변을 편집하고 코드를 읽을 수 있도록 포맷하십시오. – kleopatra

+1

이 코드에서 어떤 일이 벌어지고 있는지 이해할 수 없습니다. 누군가 설명 할 수 있습니까? 감사 –