Draymonders/Code-Life

c++ 为什么要有虚表

Opened this issue · 3 comments

C++为什么要弄出虚表这个东西? - 果冻虾仁的回答 - 知乎
https://www.zhihu.com/question/389546003/answer/1194780618

用c来实现对象调用的两种方式

方式1

#include <stdio.h> 
typedef struct Actress {
	int height;
	// 身高 
	int weight;
	// 体重 
	int age;
	// 年龄(注意,这不是数据库,不必一定存储生日) 
	void (*desc)(struct Actress*);
} Actress;
// obj中各个字段的值不一定被初始化过,通常还会在类内定义一个类似构造函数的函数指针,这里简化 
void profile(Actress* obj) {
	printf("height:%d weight:%d age:%d\n", obj->height, obj->weight, obj->age);
}
int main()
{
	Actress a;
	a.height = 168;
	a.weight = 50;
	a.age = 20;
	a.desc = profile;
	a.desc(&a);
	return 0;
}

方式一需要函数指针绑定a.desc = profile;, 因此需要多余的函数指针消耗

方式二

#include <stdio.h> 
typedef struct Actress {
	int height;
	// 身高 
	int weight;
	// 体重 
	int age;
	// 年龄(注意,这不是数据库,不必一定存储生日)
} Actress;
void desc(Actress* obj) {
	printf("height:%d weight:%d age:%d\n", obj->height, obj->weight, obj->age);
}
int main() {
	Actress a;
	a.height = 168;
	a.weight = 50;
	a.age = 20;
	desc(&a);
	return 0;
}

c++经过编译器后会变成类方式二的代码

划重点

  • C++中类和操作的封装只是对于程序员而言的。而编译器编译之后其实还是面向过程的代码。编译器帮你给成员函数增加一个额外的类指针参数,运行期间传入对象实际的指针。类的数据(成员变量)和操作(成员函数)其实还是分离的。

至于为什么有虚表呢,是为了面向对象的多态服务的

demo

class fa {
  string nane;
  virtual show() {
    cout << "fa: " <<  name << endl;
  }
};

class son : public fa {
  virtual show() {
    cout << "son: " << name << endl;
  }
};

我们在调用fa* a = new son(); a->name="233"; a->show(); 会展示什么呢