2013-02-18 3 views
0

요소가 클래스 내에있는 벡터 내부 요소의 위치를 ​​얻는 방법은 무엇입니까? 이 일을하는 방법이 있습니까?std :: vector 내에서 요소 위치 가져 오기

예제 코드 : MAIN.CPP에서

class Object 
{ 
    public: 
    void Destroy() 
    { 
     // run some code to get remove self from vector 
    } 
} 

:

std::vector<Object> objects; 
objects.push_back(<some instances of Object>); 
// Some more code pushing back some more stuff 

int n = 20; 
objects.at(n).Destroy(); // Assuming I pushed back 20 items or more 

그래서 내가 반환하는 클래스의 구성원 인 방법 또는 무언가를 쓸 수 있기를 원하는 것 같아요 벡터 내부의 자체 위치 ... 가능합니까?

편집 :

혼란 때문에 더 잘 설명해야합니다.

void Destroy(std::vector<Object>& container){ 
    container.erase(?...?); 
} 

문제는 어떻게 삭제 번호를 찾을 수 있습니까? 분명히 이것은 불가능합니다 ... 나는 생각하지 않을 수도 있습니다 ...

+0

당신이 필요로하는 의미론을 반영하는 클래스에 대한 적절한 비교 연산자를 작성한 다음'std :: find'를 사용하십시오. – us2012

+2

오브젝트가 벡터,리스트 또는 큐의 멤버 인 경우, 오브젝트는 왜 신경을 썼겠습니까? –

+0

방금 ​​말한 것을 이해하지 못할 까봐 걱정됩니다. 나는'operator == (...)'를 써야하고 std :: find를 사용하면 어떤 코드가 무엇을 하는가? – user3728501

답변

0

벡터의 객체는 벡터의 위치를 ​​자동으로 알지 못합니다.

각 개체에 해당 정보를 제공 할 수 있지만 벡터에서 개체를 제거하는 것이 훨씬 쉽습니다. 소멸자는 자동으로 실행됩니다.

다음 개체는 다른 컨테이너에서도 사용할 수 있습니다.


예 :.

#include <algorithm> 
#include <iostream> 
#include <vector> 

class object_t 
{ 
private: 
    int  id_; 
public: 
    int id() const { return id_; } 

    ~object_t() {} 
    explicit object_t(int const id): id_(id) {} 
}; 

int main() 
{ 
    using namespace std; 
    vector<object_t> objects; 

    for(int i = 0; i <= 33; ++i) 
    { 
     objects.emplace_back(i); 
    } 

    int const n = 20; 
    objects.erase(objects.begin() + n); 

    for(auto const& o : objects) 
    { 
     cout << o.id() << ' '; 
    } 
    cout << endl; 
} 
+0

예, 질문을 이해하지 못했던 것 같습니다. 파괴는 제거를 수행 할 방법입니다. – user3728501

+0

좋아요, 편집을 했으니 까, 이것을 구현해 드리겠습니다. – user3728501

1

당신은 (당신이 Object에 대한 비교 연산자 (==)를 구현 제공 vector의 요소를 찾을 수 std::find를 사용할 수 있습니다 그러나,이 큰 문제 :

  1. 컨테이너에서 요소를 찾으려면 std::map 또는 0과 같은 정렬 된 컨테이너를 사용하면 성능이 훨씬 향상됩니다.(찾을 작업은 O(log(N))O(N)
  2. Object은 컨테이너에서 자체를 제거하는 작업이 아니어야합니다. Object은 캡슐화를 깨뜨리기 때문에 어디에 있는지 모르기도하고 걱정하지 않아야합니다. 대신 컨테이너 소유자는 이러한 작업에 관심을 기울여야합니다. 당신이 벡터에서 n 번째 항목을 파괴해야하는 경우
+0

아쉽게도 캡슐화 규칙을 무시하면 더 좋습니다. – user3728501

+0

때때로? 확실한. 일반적으로 엄지 손가락으로? 기필코 아니다. 객체는 일반적으로 객체가 저장 될 컨텍스트를 "인식"하지 않아야합니다. Singletons, 개인 생성자 등을 통해 컨텍스트를 제한 할 수 있지만 소유자의 유형이 결코 긍정적이지 않은 경우가있을 수 있습니다 (경우에 따라 인터페이스가 될 수도 있음). , 가능하면 피해야합니다.) – eladidan

+0

그래, 이건 그 중 하나지만, 나는 인터페이스를 쓰지 않을거야. – user3728501

0

후 가장 쉬운 방법은 std::begin()를 사용하여 처음부터 반복자를 얻을 당신이 방법을 지금까지 많은 장소 사전에 std::advance()를 호출하는 것입니다, 그래서 뭔가 같은 :

당신이 벡터에있는 항목의 인덱스를 찾으려면
std::vector<Object> objects; 
const size_t n = 20; 

auto erase_iter = std::advance(std::begin(objects), n); 

objects.erase(erase_iter); 

다음 반복자를 취득하고 처음부터 std::distance 전화를 std::find를 사용합니다.

그래서 같은 :

Object object_to_find; 
std::vector<Object> objects; 

auto object_iter = std::find(std::begin(objects), std::end(objects), object_to_find); 

const size_t n = std::distance(std::begin(objects), object_iter); 

이것은 당신이 당신의 개체에 대한 동등 연산자를 구현해야한다는 것을 의미한다.이것은 object_to_find은 그냥 주소를 비교함에 따라 실제 목록에서 하나가 될 필요가 작업 할 수 있지만

auto object_iter = std::find(std::begin(objects), std::end(objects), 
    [&object_to_find](const Object& object) -> bool { return &object_to_find == &object; }); 

: 또는 당신은 뭔가를 시도 할 수 있습니다. 예상대로

void Destroy(std::vector<Object>& container); 
{ 
    container.erase(container.begin() + (this - &container[0])); 
} 

이것은 작동하지만 그것은 나에게로 매우 나쁜 디자인을 친다 :

+0

문제는 n 값이 무엇인지를 찾는 것입니다. – user3728501

1

목적은 thusly 히 자체를 지울 수 있습니다. 회원은 자신의 용기에 대한 지식이 없어야합니다. 그들은 (자신의 관점에서) 식별 할 수없는 림보에 존재해야한다. 창조와 파괴는 창조주에게 맡겨야한다.

+0

네,이게 내가 원하는 것 같아요. – user3728501

+0

오브젝트는'.erase()'를 호출 한 후에 더 이상 존재하지 않는다는 것을 알아 두십시오. 예를 들어, 멤버 변수를 참조하거나 멤버 함수를 호출하면 안됩니다. 안전을 위해서'.erase()'가 끝나면 할 일은'return;'입니다. –

+0

또한,이 해결책은 포인터 연산 때문에'std :: vector <> '에만 해당됩니다. 다른 컨테이너에는 인접한 객체가 없습니다. 이것은'std :: list <>','std :: set <>'등에서는 작동하지 않을 것이고'std :: vector '에서는 작동하지 않을 것이다. –

관련 문제