我们先来看看类的内存结构吧:
class A
{
int a;
public:
op(int value){a=value;};
int read(){return a ;}
public
virtual int as(){return a*a;}
};
对于以上的类的说明,当创建一个实例时,其内存结构如下(不同的C++实现略有不同):
+0000: 成员变量 int a
+0004: $A$vtable指针 --> +0000: 成员函数指针 as
为什么op函数和read函数不需要在类中体现呢?因为没有必要。
当C++编译以上的类时,它会产生类似以下的成员函数(不同的C++实现略有不同):
//op函数
int $A$op@i_(A* this, int value) {this->a = value;}
//read函数
int $A$read@_(A* this) {return this->a;}
//as函数
int $A$as@_(A* this) {return this->a * this->a;}
也就是说,函数名本身就指明了函数是属于哪个类的(连参数类型都有),因此,编译器在编译代码时,可以直接调用该类的成员函数,而不需要类本身提供任何信息。
例(0):
A a;
对于函数调用:
a.read();
此时,a是A的实例,因此编译生成代码为:
$A$read@_(&a);
例(1):
A a;
对于函数调用:
a.as();
此时,a是A的实例,因此编译生成代码为:
$A$as@_(&a);
例(2)
A* pa;
对于函数调用:
pa->read();
对应生成代码为:
$A$read@_(pa);
例(3)
A* pa;
对于函数调用:
pa->as();
对应生成代码为:
(pa->$A$vtable[0])(pa);
请注意:
如果不是用指针调用,那么是不是virtual函数,调用方法是一样的,参见例(0)和例(1)
如果是指针调用,例(2)和例(3)就是调用virtual函数和普通成员函数的区别。就因为有这区别,所以virtual函数必须在类中占一席之地
类的大小和其成员函数(非虚)没有关系
最新推荐文章于 2023-03-23 20:49:59 发布