2010-12-08 5 views
2

인터페이스와 함께 C++ 반복기를 사용하려고하지만 작동하지 않습니다.C++ 반복기, 인터페이스 및 포인터

나는 벡터 컨텐츠를 위해 어떤 유형을 선택해야할지 모르겠다. 포인터가 될 필요가 있습니까? 나는 "새로운 구현()"을해야합니까? 간단히 말해서, 그것은 나에게 불분명하며, 그에 대한 유용한 예를 찾을 수는 없습니다.

다음은 인터페이스 및 구현 (.h 파일)입니다.

class Interface{ 
public: 
virtual int method() = 0; 
}; 

class Implementation1 : public Interface{ 
    public: 
    int method(); 
}; 

class Implementation2 : public Interface{ 
    public: 
    int method(); 
}; 

.cpp 파일 :

#include "content.h" 

int Implementation1::method(){ 
    return 1; 
} 

int Implementation2::method(){ 
    return 2; 
} 

그리고 내 주요 기능 :

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

using namespace std; 

int main(void) 
{ 
    // create the vector and put elements in it 
    vector<Interface*> elements; 
    elements.push_back(new Implementation1()); 
    elements.push_back(new Implementation1()); 
    elements.push_back(new Implementation2()); 

    // now iterate on them 

    vector<Interface*>::iterator iterator; 
    for(iterator = elements.begin(); iterator != elements.end(); ++iterator){ 
     *iterator->method(); 
    } 

    return 1; 
} 

compilator이 출력됩니다 : 난 것에 대해

main.cpp: In function ‘int main()’: main.cpp:19: error: request for member ‘method’ in ‘* iterator.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator-> with _Iterator = Interface**, _Container = std::vector >’, which is of non-class type ‘Interface*’

어떤 생각 여기 잘못있는거야?

+0

"작동하지 않음"이란 무엇을 의미합니까? – kennytm

+0

컴파일 오류입니다. 예. g ++의 출력을 추가했습니다. –

답변

11

변경 *iterator->method();

(*iterator)->method(); 전직 역 참조 iterator-의 복귀> 방법(). 인터페이스 *에는 method()가 없습니다. 아무 것도 없습니다.

포인터를 얻으려면 반복기를 참조 해제 한 다음 IT 참조를 취소하십시오.

당신은 기본적으로 Iterator **와 같은 것을 가지고 있으므로 그에 따라 행동하십시오.

+3

좀 더 자세히 설명하자면,'-'는'*'보다 우선시되며'2 * 2 + 2'에서'*'와 같은 방식으로'+'보다 우선 순위가 높습니다. – Thanatos

0

은 수행하지만 원시 포인터의 벡터를 생성하는 것은 일반적으로 나쁜 생각 한 것에 대해 본질적으로 잘못된 것은 어디에도 없습니다 (*iterator)->method();

0

, 당신은 shared_ptr의 같은 소유권 시행 포인터 ("스마트"포인터)를 사용한다 시도 . 그리고 iterator를 de-reference 할 필요도 없다. 직접 method()를 직접 제공해야한다. 그러나,이 코드와 직접적으로 호환되지 않는 것은 보이지 않습니다. 어쩌면 *iterator->method()을 제외하고, 마지막으로 참조 해제가 매우 낮은 우선 순위를 가지며, 사용자는 *(iterator->method())을 수행 할 수 있습니다. 이는 비 호환입니다.

+0

원시 포인터의 벡터가 오류 가능성 (즉, 스마트 포인터의 벡터와 비교할 때)에 비해 차선책 인 경우에 대한 설명이 정확하지만 필요하지 않은 참조 카운트 된 스마트 포인터를 제안하면 문제가 해결되지 않습니다 효율성면에서 최적 임). 여전히 나쁘다. 더 나은 해결책은'boost :: ptr_vector' 또는'unique_ptr' (C++ 0x)와 같은 스마트 포인터의 평범한 벡터입니다. – Kos

2

+1 노아에 대한 반복기의 컴파일 오류에 대해서는 좋은 설명입니다. 귀하의 이전 질문에 대해서는 다음과 같습니다.

I'm a bit lost with what type to choose for the vector contents. Is this need to be a pointer ? do I have to make a "new Implementation()"?

예, 이것은 포인터 여야합니다. 이유는 간단합니다 : T 유형의 벡터는 하위 유형이 아닌 T 유형의 요소 만 저장하고 소유합니다. 그 이유는 충분합니다 (하위 클래스의 크기가 다른 경우는 무엇입니까?).

따라서 개체를 어딘가에 저장하고 포인터를 벡터에 유지해야합니다. 사실 operator new을 통해 무료 스토어에 저장하는 것이 가장 쉬운 방법입니다.

생활을 조금 더 쉽게하려면 boost::ptr_vector을 사용하면됩니다.

+2

스마트 포인터를 사용할 수도 있습니다. 예를 들어, 필요에 따라'vector >'을 사용할 수 있습니다. auto_ptr 또는 scoped_ptr을 사용하지 마십시오. 그들은 작동하는 것처럼 보이지만 합법적 인 벡터 컨텐츠는 아닙니다. –

+0

동의 함 (하지만 여전히 C++ 0x이므로 'ptr_vector'가 제 1 추천 ATM입니다). – Kos