따라서 패킷로드를 계획하는 경우 요즘 메모리는 실제로 큰 비용이 아니며 어레이는 매우 빠릅니다. 또한 switch 문을 사용하여 점프 테이블을 자동으로 생성 할 수 없으므로 점프 테이블 시나리오를 직접 생성하는 것이 더 쉽습니다. 아래 예에서 볼 수 있듯이 최대 255 개의 패킷을 가정합니다.
아래의 결과를 얻으려면 추상화가 필요합니다 .. 어떻게 작동하는지 설명하지 않을 것입니다.
(id <0)에 대한 경계 검사를 수행해야하는 것보다 더 필요한 경우 패킷 크기를 255로 설정하도록 업데이트했습니다. (id> 길이).
Packets[] packets = new Packets[255];
static {
packets[0] = new Login(6);
packets[2] = new Logout(8);
packets[4] = new GetMessage(1);
packets[8] = new AddFriend(0);
packets[11] = new JoinGroupChat(7); // etc... not going to finish.
}
public void handlePacket(IncomingData data)
{
int id = data.readByte() & 0xFF; //Secure value to 0-255.
if (packet[id] == null)
return; //Leave if packet is unhandled.
packets[id].execute(data);
}
C ++에서 점프 테이블을 많이 사용하므로 편집 이제 함수 포인터 점프 테이블의 예를 보여 드리겠습니다. 이것은 매우 일반적인 예이지만 실행했으며 올바르게 작동합니다. 포인터를 NULL로 설정해야합니다. C ++는 Java 에서처럼이를 자동으로 수행하지 않습니다.
#include <iostream>
struct Packet
{
void(*execute)() = NULL;
};
Packet incoming_packet[255];
uint8_t test_value = 0;
void A()
{
std::cout << "I'm the 1st test.\n";
}
void B()
{
std::cout << "I'm the 2nd test.\n";
}
void Empty()
{
}
void Update()
{
if (incoming_packet[test_value].execute == NULL)
return;
incoming_packet[test_value].execute();
}
void InitializePackets()
{
incoming_packet[0].execute = A;
incoming_packet[2].execute = B;
incoming_packet[6].execute = A;
incoming_packet[9].execute = Empty;
}
int main()
{
InitializePackets();
for (int i = 0; i < 512; ++i)
{
Update();
++test_value;
}
system("pause");
return 0;
}
또한 제가 언급하고 싶은 또 다른 점은 유명한 Divide and Conquer입니다. 따라서 위의 255 배열 아이디어는 최악의 시나리오로 8 if 문을 더 이상 줄일 수 없습니다.
즉, 지저분하고 빠르게 관리하기가 어렵고 다른 접근 방식이 일반적으로 더 좋지만 어레이가 그것을 자르지 않는 경우에 활용됩니다. 사용 사례와 각 상황이 가장 잘 작동하는시기를 파악해야합니다. 몇 가지 검사 만있는 경우 이러한 접근 방식 중 하나를 사용하지 않으려는 것처럼.
If (Value >= 128)
{
if (Value >= 192)
{
if (Value >= 224)
{
if (Value >= 240)
{
if (Value >= 248)
{
if (Value >= 252)
{
if (Value >= 254)
{
if (value == 255)
{
} else {
}
}
}
}
}
}
}
}