2017-09-04 2 views
1

벡터는 배열 요소가 벡터 자체의 구성원 인 것처럼 가장하는 방식으로 배열을 래핑합니다. 이것이 const 벡터의 배열 요소를 수정할 수없는 이유입니다. 벡터를 사용하면 배열 요소의 주소에 액세스 할 수도 있습니다. 그러나 벡터의 요소 인 벡터의 배열 요소에 대한 포인터를 얻은 다음 벡터에 할당하면 내 포인터가 더 이상 벡터의 요소를 가리 키도록 정의되지 않습니다. push_back() 또는 그와 비슷한 것이 포인터를 무효화하는 데 아무런 의미가 없습니다. 왜냐하면 아무도 push_back()이 벡터의 요소에 어리석은 짓을하지 않았기 때문입니다.은 할당 연산자가 해당 멤버의 위치를 ​​이동하기 때문에 정규가 아닌 형식 인 std :: vector입니다.

모든 일반 유형의 요소에 대한 내 포인터는 할당 후에도 유효합니다. 따라서, 해결 방법은 없지만 벡터를 비정규 형식으로 만들지는 않습니까?

std::string 및 기타 많은 목록/저장소 유형도 동일합니다.

편집 : 콘크리트 유형이라고 말하면 일반 유형을 의미합니다.

edit, 한 점 더 : 그래서, 구조체의 멤버에 대한 포인터를 얻었 으면, 구조체에 할당하는 것은 말 그대로 객체의 위치를 ​​변경할 수 없습니다. 배열 요소는 구조체의 일부가됩니다. 그러나 벡터에서는이 규칙이 적용되지 않습니다. 구성원은 말 그대로 동일한 개체 이름과 연결되어 있기 때문에 개체의 구성원이며 개체가 소멸 될 때까지 항상 유지됩니다. 따라서 일반적인 작업으로는 이와 같이 변경할 수 없어야합니다.

+0

"콘크리트 유형"의 정의는 여기에서 사용하고 있습니까? 표준/문서는 일반적으로 [포인터/반복기가 무효가되는 경우를 나타냅니다.] (http://en.cppreference.com/w/cpp/container/vector/push_back). – nwp

+0

"콘크리트 유형"은 일반적으로 "추상적 유형이 아님"으로 사용됩니다. 이 의미에서 벡터는 구체적인 유형입니다.여기에 무엇을 묻으려고하는지 명확하지 않습니다. 다른 곳에서 관리되지 않는 배열에 대한 포인터가 필요하면 vector 대신 array를 직접 사용하십시오. – VTT

+0

거의 대수적으로 동작하는 유형이며 모든 멤버 연산자가 정의되어 이름을 고려한 의미를가집니다. 예를 들어 operator = (something) 인 경우 operator == (something)이 true를 반환합니다. (nwp에 대한 응답) – Evan

답변

3

C++의 일반 유형 개념은 Stepanov의 프로그래밍 요소에서 비롯됩니다. 기본적으로 유형에 대한 합리적인/유용한 개념 목록입니다. 예를 들어, 동등성 및 할당을 지원해야하며 할당은 할당 된 변수가 원래 변수와 비교되는 사후 조건을 가져야합니다 (물론 이것은 복사 할당 및 이동 할당이 아닙니다).

그러나 규칙성에는 설명하는 개념이 포함되지 않습니다. 콘크리트는 완전히 다른 것입니다. 기본적으로 실제로 인스턴스화 될 수있는 모든 클래스입니다. 즉 순수 가상 메서드가 없습니다.

스테파노 프에는 귀하가 묘사하고있는 것과 관련된 분류가 있습니다. 내 사본을 편리하게 가지고 있지는 않지만 내적 대 외부라고 말합니다. 유형의 인스턴스를 구성하는 비트가 실제로 해당 값의 모든 정보를 포함하는지 여부에 대한 질문입니다. 벡터는 일반적으로 벡터 자체를 구성하는 세 개의 포인터가 완전히 설명하지 못하기 때문에 외부에 있습니다. 실제 벡터 인스턴스의 "내부"에는 포함되어 있지 않지만 벡터 표현의 일부인 힙에도 내용이 있습니다.

설명하는 문제는 벡터가 외부에 있기 때문에 발생합니다. 유형의 외부 파트로 직접 이동하는 포인터를 가져온 다음 해당 유형에 대한 연산을 수행 할 때마다 해당 포인터가 무효화 될 수 있습니다. 그러나 int와 같은 간단한 멤버가있는 struct는 내부 구조이므로 모든 정보는 struct 내부에 포함됩니다. 이것은 행동의 차이를 일으 킵니다.

동적 크기의 배열 유형을 원한다면 기본적으로 힙을 사용해야하며 힙을 사용하면 유형이 외부적일 것이라는 것을 의미합니다. 그렇기 때문에 모든 표준 컨테이너에는 반복기를 무효화 할 수있는시기에 대한 자세한 설명이 있습니다.