一、C++代码片段一:
#include <cstdio>
#include <cstdint>
#include <cstdlib>
class ISpeaker{
protected:
size_t b;
public:
ISpeaker( size_t _v )
: b(_v)
{}
virtual void speak() = 0;
};
class Dog : public ISpeaker {
public:
Dog()
: ISpeaker(0)
{}
//
virtual void speak() override {
printf("woof! %llu\n", b);
}
};
class Human : public ISpeaker {
private:
size_t c;
public:
Human()
: ISpeaker(1)
, c(2)
{}
virtual void speak() override {
printf("hello! %llu\n", c);
}
};
int main( int argc, char** _argv ) {
Human* pHuman = new Human();
Dog* pDog = new Dog();
//
ISpeaker* speaker1 = (ISpeaker*)pHuman;
ISpeaker* speaker2 = (ISpeaker*)pDog;
//
speaker2->speak();
speaker1->speak();
//
return 0;
}
二、翻译后的C代码片段一:
#include <cstdio>
#include <cstdlib>
#include <cstdint>
extern "C" {
struct SpeakerTable {
void(* speak )( void* _ptr );
};
void __dog_speak( void* _ptr ) {
uint8_t* p = (uint8_t*)_ptr;
p+=sizeof(SpeakerTable*);
size_t b = *((size_t*)p);
printf("woof! %llu\n", b);
}
void __human_speak( void* _ptr ) {
uint8_t* p = (uint8_t*)_ptr;
p+=sizeof(SpeakerTable*);
p+=sizeof(size_t);
size_t b = *((size_t*)p);
printf("hello! %llu\n", b);
}
const static SpeakerTable __dogSpeakTable = {
__dog_speak
};
const static SpeakerTable __humanSpeakTable = {
__human_speak
};
struct __ispeaker {
const SpeakerTable* vt;
size_t b;
};
struct __dog {
const SpeakerTable* vt;
size_t b;
};
struct __human {
const SpeakerTable* vt;
size_t b;
size_t c;
};
__dog * createDog() {
__dog* ptr = (__dog*)malloc(sizeof(__dog));
ptr->vt = &__dogSpeakTable;
ptr->b = 0;
return ptr;
}
__human* createHuman() {
__human* ptr = (__human*)malloc(sizeof(__human));
ptr->vt = &__humanSpeakTable;
ptr->b = 1;
ptr->c = 2;
return ptr;
}
};
int main( int _argc, char** _argv ) {
__dog* dog = createDog();
__human* human = createHuman();
//
__ispeaker* speaker1 = (__ispeaker*)dog;
__ispeaker* speaker2 = (__ispeaker*)human;
//
speaker1->vt->speak(speaker1);
speaker2->vt->speak(speaker2);
return 0;
}
三、C++代码片段二:
#include <cstdio>
#include <cstdint>
#include <cstdlib>
class IRunner {
private:
size_t a;
public:
IRunner()
: a(0)
{
}
virtual void run() = 0;
};
class ISpeaker {
protected:
size_t b;
public:
ISpeaker(size_t _v)
: b(_v)
{}
virtual void speak() = 0;
};
class Dog : public ISpeaker {
public:
Dog()
: ISpeaker(1)
{}
//
virtual void speak() override {
printf("woof! %llu\n", b);
}
};
class RunnerDog : public IRunner, public Dog {
public:
RunnerDog()
{}
virtual void run() override {
printf("run with 4 legs\n");
}
};
int main(int argc, char** _argv) {
RunnerDog* pDog = new RunnerDog();
Dog* simpleDog = new Dog();
pDog->speak();
{ // 等价于
ISpeaker* speaker1 = static_cast<ISpeaker*>(pDog);
speaker1->speak();
}
ISpeaker* speaker = static_cast<ISpeaker*>(simpleDog);
RunnerDog* runnerDog = dynamic_cast<RunnerDog*>(speaker);
// RTTI 信息
if (runnerDog) {
runnerDog->run();
}
//
// 子类 -> 基类 ( static_cast<>() )
// 基类 -> 子类 ( dynamic_cast<>() )
// 有可能变化
// RunnerDog* runnerDog = (RunnerDog*)(speaker);
return 0;
}
四、翻译后的C代码片段二:
#include <cstdio>
#include <cstdlib>
#include <cstdint>
extern "C" {
#define RTTI_INFORMATION
struct RunnerTable {
RTTI_INFORMATION
void(*run)(void* _ptr);
};
struct SpeakerTable {
RTTI_INFORMATION
void(*speak)(void* _ptr);
};
void __dog_run(void* _ptr) {
printf("run with 4 legs");
}
void __dog_speak(void* _ptr) {
uint8_t* p = (uint8_t*)_ptr;
p += sizeof(SpeakerTable*);
size_t b = *((size_t*)p);
printf("woof! %llu\n", b);
}
const static RunnerTable __dogRunnerTable = {
RTTI_INFORMATION
__dog_run
};
const static SpeakerTable __dogSpeakTable = {
RTTI_INFORMATION
__dog_speak
};
struct __dog {
const SpeakerTable* vt;
size_t b;
};
struct __runner_dog {
const RunnerTable* vt1;
size_t a;
const SpeakerTable* vt2;
size_t b;
};
__dog * createDog() {
__dog* ptr = (__dog*)malloc(sizeof(__dog));
ptr->vt = &__dogSpeakTable;
ptr->b = 0;
return ptr;
}
__runner_dog* createRunnerDog() {
__runner_dog* ptr = (__runner_dog*)malloc(sizeof(__runner_dog));
ptr->vt1 = &__dogRunnerTable; // 经过赋值之后vt1的结构体首地址等于一个具体的函数地址
ptr->a = 0;
ptr->vt2 = &__dogSpeakTable;
ptr->b = 1;
return ptr;
}
};
int main(int _argc, char** _argv) {
__dog* dog = createDog();
__runner_dog* runnerDog = createRunnerDog();
SpeakerTable** speaker = nullptr;
{
uint8_t* ptr = (uint8_t*)runnerDog;
size_t offset = offsetof(struct __runner_dog, vt2);
ptr += offset;
speaker = (SpeakerTable**)ptr; // 等价于vt2
}
// (*speaker)之后就为vt2,调用结构体(SpeakerTable)中的函数
(*speaker)->speak(speaker);
// 等价于
runnerDog->vt2->speak(speaker);
// 但不等价于
runnerDog->vt2->speak(runnerDog); // 这是错误的
//
return 0;
}
五、图示:

六、代码来源:
本代码Copy自:【十分钟带你搞明白虚函数、虚表、多态的原理以及多重继承带来的问题-哔哩哔哩】 https://b23.tv/C5nszGl
七、另外的参考链接:
https://shenchunxu.blog.youkuaiyun.com/article/details/54143987