멀티 캐스트 메시지를받는 시스템을 업데이트하고 데이터를 클래스로 파싱 한 다음 대기열을 통해 별도의 스레드에 기본 클래스 포인터를 전달합니다. 그런 다음 다른 스레드는 클래스에서 데이터 을 읽어 테이블에 저장합니다.정적 및 동적 캐스팅을 모두 피하십시오.
두 가지 종류의 메시지가 있습니다. 여기
class BaseMsg
{
public:
BaseMsg(char tp) : msgType(tp) {}
virtual ~BaseMsg() = 0;
char msgType;
}
class MsgType1 : public BaseMsg
{
public:
MsgType1(int a, int b) : BaseMsg('1'), val1(a), val2(b) {}
virtual ~MsgType1();
int val1, val2;
}
class MsgType2 : public BaseMsg
{
public:
MsgType2(double a, double b) : BaseMsg('2'), val1(a), val2(b) {}
virtual ~MsgType2();
double val1, val2;
}
수신 코드 것 : 여기
void reciveMessage(char *datablob, MsgQueue *queue)
{
BaseMsg *msgReceived;
char type = datablob[0]; // message type is the first character in the data,
// the rest of the blob varies based on that type
if (type == '1') {
// code for parsing type 1 into 2 ints, i1, i2
msgReceived = new MsgType1(i1, i2);
} else {
// code for parsing type 2 into 2 doubles, d1, d2
msgReceived = new MsgType2(d1, d2);
}
queue->push(msgReceived);
}
는 별도의 스레드에서 실행되는 프로세스 코드의 다음은 클래스 디자인의 내가 아는
void processMessage(MsgQueue *queue)
{
BaseMsg *msgToProcess = queue->pop();
if (msgToProcess->msgType == '1') {
MsgType1 *mt1 = static_cast<MsgType1 *>(msgToProcess);
// do stuff with the message type 1 data
} else {
MsgType2 *mt2 = static_cast<MsgType2 *>(msgToProcess);
// do stuff with the message type 2 data
}
}
해당 메시지 유형에 대한 검사 다운 캐스팅은 엉망이지만, 대기열을 통해 을 통신해야하는 제약이 주어지면 더 나은 솔루션을 찾을 수 없었습니다. 성능상의 이유로 수행하고 싶지 않은 인 dynamic_cast <을 사용해도 동일한 문제가 발생합니다. 여전히 을 알고 있어야합니다. msgToProcess를 변환 할 클래스의 유형.
캐스팅 체크를 없애려면 어떻게해야합니까? & 캐스팅? 나는 많은 경험이있다 with C & C++,하지만 OO 디자인은 그리 많지 않다. 그래서 내가 알지 못하는 방법이있을 수있다.
또한이 질문을 설명하기 위해 극단적으로 요약 된 예제입니다. 실제로 은 50 가지가 넘는 메시지 유형으로, 초당 수백만 개의 메시지를 수신 할 수 있으므로 성능이 중요합니다.
"할 일"섹션에는 imp 할 수있는 방법이 있습니까? 기본 클래스에서 가상 함수 호출의 관점에서 참조하십시오. – RyanP
'downcast'가 사용되는 장소의 수를 최소화 할 수는 있지만 피할 수는 없습니다. 덜 반복적으로 사용하는 방법에 대한 아이디어는 [다른 SO 포스트에 대한 내 답변] (http://stackoverflow.com/a/43038856/434551)을 참조하십시오. –
RTTI (캐스팅)에 의존하기를 원하지 않는다면 차별적 인 유니온을 사용하고 싶을 수도 있지만 enum에 대한 switch 문이 필요합니다. 비슷한 작업을 수행하는 std :: variant도 있습니다. 나는 성능을 시도하지는 않았지만 어떤 종류의 간접 지정도 저장할 필요가 없으므로 캐시의 지역성으로부터 이점을 얻을 수 있기 때문에 실제로는 빠를 것이라고 가정합니다. – AlexG