在开始之前,首先科普一下cout指针的知识,这样才能在测试程序中很好的理解:
看下面的代码:
void main(void)
{
int a = 10;
int *p = &a; cout << a << endl;
cout << p << endl;
cout << *p << endl;
cout << &a << endl;
}
执行结果:
从代码和执行的结果可以看出cout的实现原理:cout<<后面接一个变量的标识符,然后把这个标识符转换成对应的内存地址的门牌号,然后输出这个门牌号里存储的数据。
特别地:cout<<一个指针的时候,要弄明白两件事,输出的结果是这个指针所指向的内存单元的门牌号码,同时还要弄明白这个指针变量的实际存放在内存的哪个内存单元里面。例如:cout<<p这个的输出是p指向的内存单元的门牌号,也就是a的门牌号,但是p的实际存放位置在p对应的内存空间中。
看一个复杂的模型:
- &d表示这个类对象的指针,cout<<(&d)输出的是这个对象的内存地址,这个地址原来存放在了符号表中。
- (int*)(&d)表示一个指向int类型的指针,但是这个指针的起始地址和&d是一样的,只是类型改变了。cout<<((int*)(&d))输出的值和cout<<&d是一样的。
- *(int*)(&d)表示一个指向虚函数表的指针,这个指针指向的是虚函数表的起始地址,cout<<这个指针的结果是这个指针所指向的内存单元的门牌号。同时,存储这个指针变量的内存单元是_vptr_Derived,所以得到的输出结果是存储在Derived对象中的,也就是_vptr_Derived的值。
- (int*)*(int*)(&d)+1指向虚函数表中第二个slot的指针,cout<<的结果是指向内存单元的门牌号。这个指针是计算得到的,没有内存单元存放这个指针变量的值。
- *((int*)*(int*)(&d)+1)这个指针指向void Derived::print(void) const这个函数的函数指针,但是cout这个指针的结果是这个指针所指向的内容的门牌号,但是这个指针的值实际存放的内存位置是虚函数表中的第二个slot的内容。