class edge 의 attribute으로는 std::string 으로 표현하는 두 개의 노드만을 갖는다. operation 으로는 생성자류, 파괴자, operator <, =, ==, 그리고 attribute인 두 노드를 반환하는 함수를 정의해 보자. 헤더 파일은 다음과 같다.
#ifndef __DEFINITION_OF_EDGE__
#define __DEFINITION_OF_EDGE__
#include <string>
class edge{
private:
std::string _node1;
std::string _node2;
public:
edge();
edge(const std::string& n1, const std::string& n2);
edge(const edge& e);
std::string first() const;
std::string second() const;
bool operator<(const edge& e)const ;
bool operator==(const edge& e) const ;
edge& operator=(const edge& e);
virtual ~edge();
std::pair<std::string,std::string> get_node_pair() const ;
};
#endif
복사 생성자라던가 attribute을 반환하는 함수는 다음과 같은데 너무 뻔하므로 다음으로 넘어 가자.
operator== 및 operator= 는 다음과 같이 정의할 수 있을 것이다.
bool edge::operator==(const edge& e) const {
if(_node1 == "" || _node2 == "") return false;
if(_node1 == e._node1 && _node2 == e._node2) return true;
if(_node1 == e._node2 && _node2 == e._node1) return true;
return false;
}
edge& edge::operator=(const edge& e){
if(*this == e) return *this;
_node1 = e._node1;
_node2 = e._node2;
return *this;
}
operator== 는 parameter로 edge 객체를 받는데, 함수 내부에서 parameter로 받은 edge 객체를 수정하지 않을 것으므로 const 로 받는다. 아무래도 node를 표현하는 string 타입의 identifier가 그리 크지는 않을테지만 string 이므로 메모리를 많이 잡아먹을 수 있다는 가정이 들어 가며, 그 경우 call by value로 호출하게 되면 조금 부담이 될 수 있다. 그러므로 const 로 받는다. 또한 operator== 는 함수 내부에서 edge class의 유일한 attribute인 [_node1]과 [_node2]를 변경시키지 않을 것이므로 member function 자체도 const로 선언한다. 하는 기능은 다소 직관적인데, 현재 구현하는 것이 방향성이 없는 edge 이므로 두 노드가 순서에 상관없이 같으면 참을 반환한다. 논리에 따라 parameter로 받은 e 역시 빈 노드를 가지면 거짓이 반환됨을 알 수 있다.
operator= 는 역시 직관적이다. 단 이 경우 operator== 와는 달리 현 객체의 attribute인 두 노드의 값을 수정하기 때문에 operator= 는 const 가 아니다.
다음으로는 가장 난해한 operator< 를 구현해 보자. 이 함수를 구현해야 edge type으로 된 변수들을 STL의 set 이나 map 에 집어 넣을 수 있으므로 잘 정의해야 한다. 현재는 단지 ordering 만 잘 하면 되는 것일 뿐 여기서 정의한 '크다'라는 것이 별다른 의미를 지니지 않으므로 STL의 spec에서 요구한 조건인 strict weak ordering만 되도록 하면 된다.
bool edge::operator<(const edge& e) const {
const std::string& max1 = (_node1 > _node2 ? _node1 : _node2);
const std::string& max2 = (e._node1 > e._node2 ? e._node1 : e._node2);
if(max1 == max2){
const std::string& min1 = (_node1 < _node2 ? _node1 : _node2);
const std::string& min2 = (e._node1 < e._node2 ? e._node1 : e._node2);
return min1 < min2;
}
return max1 < max2;
}
위 정의는, 노드의 값 중 큰 값을 갖는 edge 형 변수가 크다는 정의이다. 만약 두 값중 큰 노드의 값이 같다면 작은 값이 큰 변수가 크다고 할 수 있다. 이와 같이 정의된 opeartor< 는 strict weak ordering 이 되기 때문에 STL의 map과 set에 집어 넣을 수 있게 된다.
참고글
1. no match for ‘operator<’ in ‘__x < __y’
2. strict weak ordering
'컴퓨터 > C++_STL' 카테고리의 다른 글
동적 라이브러리 만들고 사용하기 (5) | 2010.05.25 |
---|---|
Strict weak ordering (4) | 2010.05.11 |
파일 목록 가져 오기 일반화 시키기 (0) | 2010.01.09 |
멤버 함수의 포인터를 배열에 넣는 방법 (0) | 2009.12.27 |
template과 iterator 변수 사용하기 (2) | 2009.12.27 |