반응형

Java에서 사용자가 정의한 클래스를 java.util.HashMap에서 key 값으로 사용하도록 만들 때, Overriding 메쏘드 중에서 hashCode 메쏘드를 제대로 구현해야 문제없이 작동한다. 사용자 정의 클래스의 몇몇 멤버변수 값들이 다른데도 불구하고 hashCode를 제대로 구현하지 않으면 차이가 없는 것으로 판단할 수도 있기 때문이다.


C++에서는 map<const Key, T>이 비슷한 역할을 하는데, Java처럼 hashCode 함수 대신 operator < 함수를 써서 키값을 비교하는 것으로 생각된다. 

처음에는 operator = 함수만 신경써서 만들고, 실수로 operator < 함수의 내부 구현을 대충 했더니, map의 key로 서로 다른 멤버변수 값을 갖는 클래스를 대입했는데 모두 같은 value를 리턴하는 것이었다.


내 경우에는 네트워크 상의 트래픽을 표현하기 위해 Flow라는 클래스를 아래와 같이 정의했다.


class Flow {

public:

std::string srcIp;

int srcPort;

std::string dstIp;

int dstPort;

int type;

Flow();

~Flow();

};


그리고 실수로 "operator <" 함수를 아래와 같이 간단하게 만들었더니,


bool Flow::operator <(const Flow& ref) const {

return (this->srcPort + this->dstPort) < (ref.getSrcPort() + ref.getDstPort()));

}


source 또는 destination IP 주소가 서로 다른 여러 개의 flow가 모두 같은 key 값을 갖게 되는 문제가 발생했다.


그래서 std::string 형식의 IP 주소에서 숫자를 빼내서 이것들도 모두 더하는 방식으로 operator <를 구현해서 key 값이 서로 달라지도록 만들었다.


bool Flow::operator <(const Flow& ref) const {

return ((convert(this->srcIp) + this->srcPort + convert(this->dstIp) + this->dstPort) < (convert(ref.getSrcIp()) + ref.getSrcPort() + convert(ref.getDstIp()) + ref.getDstPort()));

}


이런 부분에서의 실수는 컴파일 에러에서 전혀 잡히지 않고, 가끔은 Segmentation fault 같은 에러조차 발생시키지 않고서 정상적이면서 의미상으로만 이상하게 작동하기 때문에 앞으로는 더 주의해야 할 것이다.



반응형
블로그 이미지

Bryan_

,