를 호출하는 방법 const_iterator 임을 위한 비 const class?[중복]
문제
내가 읽고 다른 스레드 관련하여 이 문제지만 비 솔루션을 제공한 문제입니다.나는 당신들이 나에게 아이디어를 제공하거나 조언이 있습니다.
나를 구현하기 위해 노력하고 이 클래스 이름 Map
.그것은 포함해야 합 2 반복기- iterator
고 const_iterator
.
나는 그들이 구현- iterator
에서 상속 const_iterator
, 고 Map
클래스에는 다음과 같은 기능이 있습니다:
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
우리가 주어진 예를 들어 파일을 참조하기 위해 필요한 것 구현할 수 있습니다.거기에있다,다음 코드:
Map<std::string,int> msi;
...
// print map
for(Map<std::string,int>::const_iterator it = msi.begin(); it != msi.end(); ++it) {
// more stuff here
}
이 msi
non-const 지도를 들어, msi.begin()
전화 iterator begin()
지 const_iterator begin() const
, 의 결과,의도하지 않은 행동을 했다.
가정 예 파일 좋아,내가 어떻게 그렇게 msi.begin()
올바른 통화 const_iterator
기능입니까?(고려하고,반복기,유형 const_iterator
).
편집:에 관한 이야기에 대한 자동 전환,나를 추가하기로 결정 나의 클래스의 반복기,주십시오 나의 실수입니다.
class Map {
//...
public:
class const_iterator {
private:
Node* currNode;
public:
const_iterator(Node* cur_node = NULL) : currNode(cur_node) {}
const_iterator& operator++() {
currNode = currNode->next;
return *this;
}
const_iterator operator++(int) {
const_iterator old = *this;
++(*this);
return old;
}
bool operator!=(const_iterator const& curr) {
return !(*this == curr);
}
string operator*() {
// this might cause memory leak
string toString(this->currNode->key);
std::stringstream s;
int tmp = this->currNode->value;
s << tmp;
string secondString(s.str());
toString = toString + ":" + secondString;
return toString;
}
bool operator==(const_iterator const& curr) {
return this->currNode == curr.currNode;
}
void operator=(const_iterator target) {
this = target;
}
//void operator=(Node* target) {
// this->currNode = target;
//}
};
class iterator : public const_iterator {
private:
Node* currNode;
public:
iterator(Node* cur_node = NULL) : currNode(cur_node) {}
iterator& operator++() {
currNode = currNode->next;
return *this;
}
iterator operator++(int) {
iterator old = *this;
++(*this);
return old;
}
bool operator==(iterator const& curr) {
return *this == curr;
}
bool operator!=(iterator const& curr) {
return !(*this == curr);
}
string operator*() {
// this might cause memory leak
string toString(this->currNode->key);
std::stringstream s;
int tmp = this->currNode->value;
s << tmp;
string secondString(s.str());
toString = toString + ":" + secondString;
return toString;
}
void operator=(iterator target) {
this = target;
}
};
//..
}
해결책
C++11 표준 컨테이너 추가 cbegin
고 cend
는 것을 그 목적으로 한다.부족 할 수 있다는 것은 분명히 항상 객체를 캐스팅 const&
명시적으로 얻 const
기에 객체입니다.
더 근본적으로,그러나 없는 이유 iterator
지 지원을 자동 전환 const_iterator
.는,당신을 변경하지 않는 클라이언트에 코드를 모두.사실에서,코드는 이미 이를 지원하는 경우,당신이 말했듯이, iterator
에서 상속 const_iterator
.
그러나 코드를 게시 포함되어 여러 가지 오류가 있습니다.첫째, operator=
잘못된 부분이 있어야 합 오류를 받았습니다.수정된 버전입니다:
void operator=(const_iterator target) {
currNode = target.currNode;
}
더 중요한 것은,기업 다음 사항을 포함합니다.사실,당신 마 inherit iterator
서 const_iterator
그러나 당신의 코드는 척하는 이 일이 결코– iterator
완전 reimplements 부모 등과 관련 하지 않습니다.
iterator
오히려은 다음과 같이 보일 것입니다:
class iterator : public const_iterator {
public:
iterator(Node* cur_node = NULL) : const_iterator(cur_node) {}
};
이 물론 필요합니다 currNode
선언 protected
에 const_iterator
.그래도 완전히 쓸모(하지만 너무 당신을,순간)지 않기 때문에 모든 기능을 추가할을 const_iterator
클래스입니다.필요하신을 구현하는 operator*
는 수정할 수 있도록 허용 값을 의미합니다.현재 코드를 근본적으로 허용하지 않는 이 때문에 그것을 반환 새로 생성한 문자열이 아닌(에 가까운 무언가가)참조해도 값입니다.
또한,그것은 불분명하는 방법 const_iterator
클래스의 연락 비const
Node
포인터에서 첫 번째 장소입니다.하는 수 없이 가능하다:후에도,그것은 얻는 포인터부터 const Map
.
다른 팁
면을 정의합니다 msi
const Map<std::string,int> msi;
대
Map<std::string,int> msi;
const 버전의 시작()및 end()호출됩