2014-04-14 1 views
4

저는 STL 라이브러리로 작업하고 있으며 데이터 재 할당의 경우를 최소화하는 것을 목표로하고 있습니다. 내가 wndering했다 는 크기가 변경되지 않은 경우std :: vector :: assign - 데이터를 다시 할당 하시겠습니까?

표준 : : 벡터 :: 할당 (말하자면 size_type n을, CONST VALUE_TYPE & 발)

데이터를 재 할당을 수행하거나 실제로 단지를 지정한다 않습니다 새로운 값 (예 : operator =) 사용? http://www.cplusplus.com/에서

STL과 문서

은 (C++ 98) 다음 SAIS : 충전 판 (2)에서

새로운 콘텐츠 브로 사본 초기화 요소 각각은 N이다. 재 할당이 발생하면 필요한 기억 장치가 내부 할당자를 사용하여 할당됩니다.

호출하기 전에 컨테이너에 보관 된 요소는 모두 삭제되고 새로 생성 된 요소로 대체됩니다 (요소 할당이 수행되지 않음). 새로운 벡터 크기가 현재 벡터 용량을 초과하는 경우에만 할당 된 저장소 공간을 자동으로 다시 할당합니다.

"요소가 지정되지 않았습니다"라는 문구는 모두 약간 혼란 스럽습니다.

예를 들어 OpenCV의 cv :: Vec3i와 같은 클래스의 벡터가 필요합니다.

  1. cv :: Vec3i의 소멸자 또는 생성자가 호출됩니까?
  2. Vec3i 메모리의 직접 복사가 만들어지고 벡터가 채워 집니까?
  3. 내 클래스가 런타임에 메모리를 할당 할 경우 operator? 이 메모리는 일반 메모리 복사로 처리 할 수 ​​없습니다. assign()을 객체에 사용해서는 안된다는 뜻입니까?

편집 :이 경우 지정 사용의 전체 목적은 0 벡터의 모든 값을 설정하는 것입니다 (경우에 나는 성병 한 : 벡터에게 < 이력서를 :: Vec3i> V). 그것은 여러 번 행해질 것입니다. std :: vector 자체의 크기는 변경되지 않습니다.

for(int i=0; i<v.size(); i++) 
    for(int j=0; j<3; j++) 
    v[i][j] = 0; 

지금 내가 경우 벡터를 재 할당하지 않습니다 C++ 98

+0

재 할당을 최소화하려면'std :: shared_ptr'을 사용하십시오. 이 포인터를 다른 컨테이너로 자유롭게 복사 할 수 있으며 포인터 자체 만 복사됩니다. "읽기 전용"객체 접근법을 사용하면이 문제를 해결할 수 있습니다. – Flovdis

+0

"no assignment of elements ..."가 의미하는 것은 새로운 요소가 매개 변수에서 복사 생성되고 복사 할당이 발생하지 않는다는 것입니다. 따라서 저장된 유형에 대해 잘 정의 된 사본 식별자가 있으면 걱정할 필요가 없습니다. – bstamour

+0

@Flovdis는 C++ 11의 일부 ptr과 공유되지 않습니까? 우리가 C++ 98에 대해 이야기하고 있다고 생각했습니다. –

답변

0

std::vector.assign(...)에 관심이 :

내가 (짧은 방법)하고 싶은 것은 다음은 그것을 키울 필요가 없습니다. 여전히 실제 요소를 복사해야합니다.

당신이 표준 보장, 표준에서 어떻게 보이는지 알고 싶다면

: vector::resize 방법의 경우에서와 같이 C++11 standard plus minor editorial changes.

0

,

std::vector::assign(size_type n, const value_type& val) 

가 발 "의 사본 각 요소를 초기화합니다 ". 나는 객체 instanciations/destructions의 수를 최소화로 resize을 사용하는 것을 선호하지만, 그것은 동일 않습니다. 데이터 재 할당을 최소화하려면 다음과 같이하십시오.

이 작업은 특정 데이터 구조에서는 안전하지만 동적으로 할당 된 데이터에 대한 포인터를 포함하는 클래스의 요소를 할당/밀어 넣는 것이 중요합니다 (예 : 생성자에 new이있는 경우) 혼란을 일으킬 수 있습니다.

클래스가 동적으로 데이터을 할당하는 경우 YourClass::operator=을 다시 구현해야 포인터를 복사하는 대신 데이터를 새 개체에 복사해야합니다.

도움이 되길 바랍니다.

1

난 당신이 몇 가지 데이터로 채워 벡터가 있다고 가정하고,이 것이상의 할당 전화 : 취소 전화처럼 (자신의 소멸자가 호출)

  1. 이 벡터의 모든 요소를 ​​파괴()
  2. 현재 빈 벡터를 n 개의 복사본으로 채 웁니다.이 복사본에는 복사 생성자가 있어야합니다.

가 재 할당 때 크기 일 소멸자에

  • 무료로 복사 생성자이의

    1. 돌봐 :

    그래서 클래스는 당신이 가지고 일부 메모리를 할당하는 경우 할당 된 메모리 (벡터 용량)를 초과합니다. reserve() 호출을 사용하여이를 방지 할 수 있습니다. 그러나 나는 그 할당을 시작하기 전에 (그리고 이미 할당 된 것보다 많은 경우) assign()이 필요한 모든 메모리를 할당 할만큼 똑똑하다고 생각합니다.

    비용 때문에 재 할당을 피할 수 있지만 개체가 제대로 처리 할 수 ​​없어서 피하려고하는 경우 벡터에 넣지 않는 것이 좋습니다. assign

  • +0

    +1합니다. 핵심은 '용량'으로, 적어도 이전 크기만큼 커야합니다. – MSalters

    1

    의미는 아주 간단한 방식으로 기준을 정의되어

    무효 지정 (말하자면 size_type n을 CONST T & t);

    효과 :

    erase(begin(), end());
    insert(begin(), n, t);

    이것은 첫번째 요소 소멸자가 호출되는 것을 의미한다.t의 복사본은 요소의 수명이 끝난 후 남아있는 원시 저장소로 만들어집니다.

    요구 사항은 value_typeMoveAssignable (erase은 컨테이너의 끝까지 지우지 않고 요소를 처음으로 이동해야 할 때)입니다. 여기에 사용

    insert 과부하가 value_type 어떤 경우 CopyInsertableCopyAssignable.

    을 것을 요구, 벡터 클래스가 자신의 자원을 관리하는 방법을 모른다는 것입니다. 그게 당신이 처리해야 할 일입니다. The Rule of Three.