C ++에서 벡터 요소에 대한 포인터 반환
전역 범위에 myObjects 벡터가 있습니다. 를 사용 std::vector<myObject>::const_iterator
하여 벡터를 탐색하고 특정 요소를 찾기 위해 몇 가지 비교를 수행 하는 방법이 있습니다. 필요한 요소를 찾으면 해당 요소에 대한 포인터를 반환 할 수 있기를 원합니다 (벡터는 전역 범위에 있음).
를 반환 &iterator
하면 반복기의 주소 또는 반복기가 가리키는 주소를 반환합니까?
const_iterator
myObject로 다시 캐스팅 한 다음 해당 주소를 반환해야합니까?
반복자가 가리키는 사물의 주소를 반환합니다.
&(*iterator)
편집 : 약간의 혼란을 해결하려면 :
vector <int> vec; // a global vector of ints
void f() {
vec.push_back( 1 ); // add to the global vector
vector <int>::iterator it = vec.begin();
* it = 2; // change what was 1 to 2
int * p = &(*it); // get pointer to first element
* p = 3; // change what was 2 to 3
}
포인터 벡터 나 동적 할당이 필요하지 않습니다.
& iterator를 반환하면 반복자의 주소가 반환됩니다. 요소를 참조하는 방법을 반환하려면 반복자 자체를 반환합니다.
반복기 / 포인터를 반환하기 위해 벡터가 전역일 필요는 없지만 벡터의 연산은 반복기를 무효화 할 수 있습니다. 예를 들어, 벡터에 요소를 추가하면 새 size ()가 예약 된 메모리보다 큰 경우 벡터 요소를 다른 위치로 이동할 수 있습니다. 벡터에서 주어진 항목 이전에 요소를 삭제하면 반복기가 다른 요소를 참조하게됩니다.
두 경우 모두 STL 구현에 따라 무작위 오류가 자주 발생하는 디버그가 어려울 수 있습니다.
주석 후 편집 : '예, 반복기를 반환하고 싶지 않았습니다 .a) const, b) 확실히 그것은 로컬, 임시 반복기 일뿐입니까? – 크라 코스
반복자는 다른 변수보다 더 많거나 적지 않은 로컬 또는 임시적이지 않으며 복사 가능합니다. 당신은 그것을 반환 할 수 있고 컴파일러는 포인터와 마찬가지로 당신을 위해 복사본을 만들 것입니다.
이제 const-ness가 있습니다. 호출자가 반환 된 요소 (포인터 또는 반복자)를 통해 수정을 수행하려면 상수가 아닌 반복기를 사용해야합니다. (반복자 정의에서 'const_'를 제거하기 만하면됩니다.)
반복자를 반환하는 것은 좋은 생각이 아닙니다. 벡터에 대한 수정 (inversion \ deletion)이 발생하면 반복기가 무효화됩니다. 또한 반복자는 스택에 생성 된 로컬 객체이므로 동일한 주소를 반환하는 것이 전혀 안전하지 않습니다. 벡터 반복기보다는 myObject로 작업하는 것이 좋습니다.
편집 : 개체가 경량이면 개체 자체를 반환하는 것이 좋습니다. 그렇지 않으면 벡터에 저장된 myObject에 대한 포인터를 반환합니다.
벡터가 전역 범위에있는 한 다음을 반환 할 수 있습니다.
&(*iterator)
이것은 일반적으로 매우 위험하다는 점을 경고 할 것입니다. 벡터가 전역 범위를 벗어나 파괴되면 myObject에 대한 모든 포인터가 유효하지 않게됩니다. 더 큰 프로젝트의 일부로 이러한 함수를 작성하는 경우 상수가 아닌 포인터를 반환하면 누군가가 반환 값을 삭제할 수 있습니다. 이것은 응용 프로그램에 정의되지 않은 치명적인 영향을 미칩니다.
나는 이것을 다음과 같이 다시 작성할 것입니다.
myObject myFunction(const vector<myObject>& objects)
{
// find the object in question and return a copy
return *iterator;
}
반환 된 myObject를 수정해야하는 경우 값을 포인터로 저장하고 힙에 할당합니다.
myObject* myFunction(const vector<myObject*>& objects)
{
return *iterator;
}
그렇게하면 파괴 될 때를 제어 할 수 있습니다.
다음과 같이하면 앱이 손상됩니다.
g_vector<tmpClass> myVector;
tmpClass t;
t.i = 30;
myVector.push_back(t);
// my function returns a pointer to a value in myVector
std::auto_ptr<tmpClass> t2(myFunction());
You can use the data function of the vector:
Returns a pointer to the first element in the vector.
If don't want the pointer to the first element, but by index, then you can try, for example:
//the index to the element that you want to receive its pointer:
int i = n; //(n is whatever integer you want)
std::vector<myObject> vec;
myObject* ptr_to_first = vec.data();
//or
std::vector<myObject>* vec;
myObject* ptr_to_first = vec->data();
//then
myObject element = ptr_to_first[i]; //element at index i
myObject* ptr_to_element = &element;
Say, you have the following:
std::vector<myObject>::const_iterator first = vObj.begin();
Then the first object in the vector is: *first
. To get the address, use: &(*first)
.
However, in keeping with the STL design, I'd suggest return an iterator instead if you plan to pass it around later on to STL algorithms.
You are storing the copies of the myObject in the vector. So I believe the copying the instance of myObject is not a costly operation. Then I think the safest would be return a copy of the myObject from your function.
Refer to dirkgently's and anon's answers, you can call the front function instead of begin function, so you do not have to write the *
, but only the &
.
Code Example:
vector<myObject> vec; //You have a vector of your objects
myObject first = vec.front(); //returns reference, not iterator, to the first object in the vector so you had only to write the data type in the generic of your vector, i.e. myObject, and not all the iterator stuff and the vector again and :: of course
myObject* pointer_to_first_object = &first; //* between & and first is not there anymore, first is already the first object, not iterator to it.
I'm not sure if returning the address of the thing pointed by the iterator is needed. All you need is the pointer itself. You will see STL's iterator class itself implementing the use of _Ptr for this purpose. So, just do:
return iterator._Ptr;
참고URL : https://stackoverflow.com/questions/641864/returning-a-pointer-to-a-vector-element-in-c
'development' 카테고리의 다른 글
pandas에서 여러 열 삭제 (0) | 2020.12.08 |
---|---|
WPF에서 AppBar 도킹 (WinAmp와 같은 화면 가장자리)을 어떻게 수행합니까? (0) | 2020.12.08 |
PHP는 다운로드 할 파일을 생성하고 리디렉션합니다. (0) | 2020.12.08 |
HTML에 대한 컬러 Git 차이 (0) | 2020.12.08 |
언제 TCP_NODELAY를 사용해야하고 언제 TCP_CORK를 사용해야합니까? (0) | 2020.12.08 |