IP(IPv4)는 내부적으로 4바이트의 정수(uint32_t)를 가지고 있습니다. 따라서 일반적으로 IP 형을 나타낼 때 uint32_t 타입을 많이 사용하게 됩니다. 하지만 IP를 나타내는 데 있어 클래스를 사용하지 않고 uint32_t 타입을 사용하게 되면 여러가지 불편한 점이 나타나게 됩니다. 이에 uint32_t 타임을 wrapping할 수 있는 클래스를 만들어 보도록 하겠습니다.
우선 IP클래스를 설계하는 데 있어어 필요한 사항들을 정리해 봅니다(클래스명은 CamelCase에 따라 "Ip"로 표기하도록 함).
(1) string으로부터 입출력을 할 수 있어야 한다.
std::string s;
Ip ip;
ip = s;
s = ip;
(2) &, |, ~ 등의 bitmask 연산이 가능해야 한다.
Ip ip1;
Ip ip2;
Ip ip3 = ip1 & ip2;
Ip ip3 = ip1 | ip2;
Ip ip3 = ~ip1;
(3) IP specific한 method가 제공되어야 한다.
Ip ip;
if (ip.isLocal()) ...;
if (ip.isBroadcast()) ...;
if (ip.isMulticast()) ...;
우선 Ip 클래스는 기본적으로 uint32_t 타입을 갖는 변수가 필요합니다. 따라서 다음과 같이 선언을 합니다.
class Ip{
protected:uint32_t m_ip;
};
(1)번을 위해서는 다음을 선언해야 겠죠.
char* operator = (Ip ip);
Ip operator = (const char* s);
하지만 (1)번은 conversion constructor 와 operator overloading을 이용해서 쉽게 구현할 수 있습니다.
Ip(const char* s);operator const char*();
string뿐만 아니라 uint32_t도 마찬가지로 따로 &, |, ~ 등의 operator를 명시할 필요가 없이 uint32_t와의 type conversion을 할 수 있도록만 하면 됩니다.
따라서 Ip 클래스는 다음과 같이 선언할 수 있습니다.
class Ip{
public:
Ip(string s); // for (1)
operator string(); // for (1)
Ip(uint32_t i); // for (2)
operator uint32_t(); // for (2)
protected:
uint32_t m_ip;
};
(A)에 의하여 상기 (1)번이, (B)에 의하여 상기 (2)번이 만족되게 됩니다. 여기에 (3)번을 만족하는 각종 method들을 추가해 줍니다. 최종적인 클래스는 다음과 같습니다.
if (ip.isLocal()) ...;
if (ip.isBroadcast()) ...;
if (ip.isMulticast()) ...;