首页 > 代码库 > 当this指针成为指向之类的基类指针时,也能形成多态

当this指针成为指向之类的基类指针时,也能形成多态

this指针:

  1)对象中没有函数,只有成员变量

  2)对象调用函数,通过this指针告诉函数是哪个对象自己谁。

  

 

 1 #include<iostream>
 2 using namespace std;
 3 class Shape
 4 {
 5 public:
 6     //void cal_display(Shape* this)
 7     void cal_display(){
 8         display();
 9         this->display();
10     }
11 private:
12     virtual void display(void) = 0;
13 };
14 
15 class Circle:public Shape
16 {
17 private:
18     void display(void){
19         cout << "this is a Circle!" << endl; 
20     }
21 };
22 
23 int main()
24 {
25     Circle c1;
26     //使用c1对象调用cal_display() 继承自基类  
27     // 在c1对象中调用 cal_display()函数 传递 指向子类对象的基类指针给 虚函数display() 形成多态 
28     c1.cal_display();
29     // 当提供接口调用 成员函数时 传递this指针 当这个指针属于子类对象时 遇到虚函数 就会形成多态
30     return 0; 
31 }

2 多态:

  [将子类对象的指针赋值给基类类型的指针],通过虚函数形成多态,

  虚函数的调用是通过虚函数表指针来实现的,

下面这段话来源于:http://www.cnblogs.com/cswuyg/archive/2010/08/21/1805153.html

四、延伸

       忽然想到了C++的多态,一句话“将子类类型的指针赋值给父类类型的指针”,多态是通过虚函数实现。对虚函数及其相关内容的原理、详细理解就不细说了。说下我的简单理解,有一个基类A和子类B、C,有一个函数以基类A的指针为参数,然后在函数里头通过指针调用基类的成员函数。假如这个被调用的基类成员函数不是虚函数,那么是不可能实现多态的,因为翻译成汇编指令的时候,调用成员函数的这个地方是一个call指令,然后这个call指令跳到某个地方去执行,这是一个固定了的地址。通过定义为虚函数,调用成员函数的这个地方是通过虚函数表指针来确定调用哪个函数的,而虚函数表指针就放在对象的地址空间中,如果对象变了,那么虚函数表指针也变了,调用的函数也就不同了。对于那个以基类A的指针为参数的函数,指针即是对象的地址,如果传递的地址是子类B或者C的对象的地址,那么虚函数表指针也就不同了,调用的成员函数也就不同了。

这就是多态,这种多态使得调用同一个函数,因为传递参数的不同而显示出差异,参数可以是基类对象或者众多不同的子类对象。它们的差异是类与类之间的。

  有虚函数的对象的内存布局,比没有虚函数的对象多了一个指向虚函数表的指针。因为虚函数的调用是通过虚函数表指针来实现的,所以有了多态。再考虑一下C++的this指针,一个类中的成员函数,依据this指针来区分不同的对象,也就是说根据this指针实现了访问不同的对象的成员变量。

这是否也是多态的一种表现?这里所说的多态已经不是那个“父类指针指向子类对象”的教条了,而是体现在同一个类的不同对象之间,调用同一个成员函数,依据参数“this指针”来实现访问不同的对象的成员变量。成员函数访问成员变量,在编译期无法确定它访问的成员变量在哪一个地址的,只有到了运行期依据this指针才能确定访问的地址。这一点很类似于类的多态:以基类指针为参数的函数里调用了某个基类的虚成员函数,在编译期无法确定程序运行时调用的会是哪个类的对象,只有到了运行期才确定会调用哪个类的对象。

  this指针识别了同一个类的不同的对象,换句话说,this指针使得成员函数可以访问同一个类的不同对象。再深入一点,this指针使得成员函数会因为this指针的不同而访问到了不同的成员变量。这也是多态吧,只是它是必然存在的多态,这种多态跟基类与派生类之间的多态是不同级别的多态,它不像一般的多态可以通过对使用虚函数的选择来取舍,它是一个类对应多个对象、多个对象共享一份成员函数代码带来的必然结果。

 

 

 

当this指针成为指向之类的基类指针时,也能形成多态