将指针从派生类型转换为基础类型的方法的最佳方法 class
Best approach for casting pointer to method from derived to base class
我们有一个基础 class 字节码,它是通用的。
ByteCode 的子代应该编写以下形式的方法:
void m();
字节码 class 应该有方法的定义:
typedef void (ByteCode::*Method)();
为了执行字节码,我们有:
void exec() {
while (true) {
uint16_t opcode = getOpcode();
Method m = opcodes[opcode];
this->*m();
}
}
一次性完成 class 没有问题。但是我们在基础 class 中有泛型代码,派生有数组:
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
}
问题是这些方法不是基础的class,它们是派生的。但是我们拥有的唯一实例是派生的,我们不想招致虚拟的开销,我们只想强制转换并使其工作,但编译器会抓住所有技巧。如果它信任我们:
Method MyByteCodeEngine ::opcodes[65536] = {
(Method)MyByteCodeEngine::m1,
(Method)MyByteCodeEngine::m2,
(Method)MyByteCodeEngine::m3
}
我们可以通过消除字节码 class 来解决这个问题,但这迫使我们在有字节码解释器的任何时候都重复代码。关于如何让 C++ 完全接受它的任何建议?
您可以使用 Curiously recurring template pattern 以便基 class 知道成员函数的类型。
template<class T>
struct ByteCode {
typedef void (T::* Method)();
void exec() {
while (true) {
uint16_t opcode = getOpcode();
Method m = T::opcodes[opcode];
static_cast<T*>(this)->*m();
}
}
};
class MyByteCodeEngine : public ByteCode<MyByteCodeEngine > {
private:
static Method opcodes[65536];
void m1() {}
void m2() {}
void m3() {}
};
MyByteCodeEngine::Method MyByteCodeEngine ::opcodes[65536] = {
&MyByteCodeEngine::m1,
&MyByteCodeEngine::m2,
&MyByteCodeEngine::m3
}
我们有一个基础 class 字节码,它是通用的。 ByteCode 的子代应该编写以下形式的方法:
void m();
字节码 class 应该有方法的定义:
typedef void (ByteCode::*Method)();
为了执行字节码,我们有:
void exec() {
while (true) {
uint16_t opcode = getOpcode();
Method m = opcodes[opcode];
this->*m();
}
}
一次性完成 class 没有问题。但是我们在基础 class 中有泛型代码,派生有数组:
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
}
问题是这些方法不是基础的class,它们是派生的。但是我们拥有的唯一实例是派生的,我们不想招致虚拟的开销,我们只想强制转换并使其工作,但编译器会抓住所有技巧。如果它信任我们:
Method MyByteCodeEngine ::opcodes[65536] = {
(Method)MyByteCodeEngine::m1,
(Method)MyByteCodeEngine::m2,
(Method)MyByteCodeEngine::m3
}
我们可以通过消除字节码 class 来解决这个问题,但这迫使我们在有字节码解释器的任何时候都重复代码。关于如何让 C++ 完全接受它的任何建议?
您可以使用 Curiously recurring template pattern 以便基 class 知道成员函数的类型。
template<class T>
struct ByteCode {
typedef void (T::* Method)();
void exec() {
while (true) {
uint16_t opcode = getOpcode();
Method m = T::opcodes[opcode];
static_cast<T*>(this)->*m();
}
}
};
class MyByteCodeEngine : public ByteCode<MyByteCodeEngine > {
private:
static Method opcodes[65536];
void m1() {}
void m2() {}
void m3() {}
};
MyByteCodeEngine::Method MyByteCodeEngine ::opcodes[65536] = {
&MyByteCodeEngine::m1,
&MyByteCodeEngine::m2,
&MyByteCodeEngine::m3
}