У нас есть базовый класс ByteCode, который должен быть универсальным.Предполагается, что потомки ByteCode будут писать методы вида:
void m();
Класс ByteCode должен иметь определение метода:
typedef void (ByteCode::*Method)();
Чтобы выполнить байт-код, мы имеем:
void exec() {
while (true) {
uint16_t opcode = getOpcode();
Method m = opcodes[opcode];
this->*m();
}
}
Выполнение этого в одном классе не будет проблемой.Но у нас есть общий код в базовом классе, а у производного есть массив:
class MyByteCodeEngine : public ByteCode {
private:
static Method opcodes[65536];
void m1() {}
void m2() {}
void m3() {}
};
Method MyByteCodeEngine ::opcodes[65536] = {
MyByteCodeEngine::m1,
MyByteCodeEngine::m2,
MyByteCodeEngine::m3
}
Проблема в том, что эти методы не являются базовым классом, они являются производными.Но единственный экземпляр, который у нас есть, является производным. Мы не хотим нести виртуальные издержки, мы просто хотим привести и выполнить эту работу, но компилятор ловит каждую хитрость.Если бы нам просто доверяли:
Method MyByteCodeEngine ::opcodes[65536] = {
(Method)MyByteCodeEngine::m1,
(Method)MyByteCodeEngine::m2,
(Method)MyByteCodeEngine::m3
}
Мы можем решить эту проблему, исключив класс ByteCode, но это вынуждает нас повторять код всякий раз, когда у нас есть интерпретатор байт-кода.Любые предложения о том, как обмануть C ++, приняв это, чисто?