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()) ...;