前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++学习笔记-对象模型,this

C++学习笔记-对象模型,this

原创
作者头像
买唯送忧
修改2021-05-04 22:09:52
2110
修改2021-05-04 22:09:52
举报
文章被收录于专栏:虚拟技术学习虚拟技术学习

一、虚指针与虚表

下面是我自己写的一段代码:A类代表Shape,B类代表quadshape,C类代表equalShape:

代码语言:javascript
复制
class Shape
{
public:
    //定义两个虚函数
    virtual void draw(){cout << "shape draw 1" << endl;}
    virtual void vfunc2(){cout << "shape func 2" << endl;}
    void func(){cout << "shape" << endl;}
private:
    int m_data1, m_data2;
};

class quadShape : public Shape
{
public:
    virtual void draw() {cout << "quadShape draw" << endl;};
private:
    int m_data3;
};

class equalShape : public quadShape
{
public:
    virtual void draw(){cout << "equalShape draw " << endl;}
};

结合代码(脑子里构思图)来说:

  1. Shape类里定义了虚函数和两个数据类型,从而在内存里开辟了三个空间,一个存放虚指针,两个存放int1数据类型,虚指针是只要你定义了虚函数就会存在。
  2. 跟着箭头走是第一个虚表,存放这个类中有几个虚函数,就像Shape类有两个虚函数,所以就存放这两个虚函数的调用地址;后面接着箭头走的就是经过Shape对象调用的虚函数
  3. 再看第二个类,它继承了Shape的全部再加上它自身的数据类型,同时它也有重写父类的虚函数,所以也有虚指针,后面的虚表因为就重写了一个,所以有一个依然和父类的函数地址一样,另一个有了自己的地址,,第三个也是如此。

二、动态绑定与静态绑定

  1. 先说静态绑定,举个例子:比如现在正在执行079地址处的语句,这一句的语句发生了函数调用,然后直接跳到了1FF处执行函数,之后返回,这样的类型叫做静态绑定
  2. 而动态绑定,则是要满足三个条件:(1)必须要通过指针调用,(2)调用的函数必须是虚函数,(3)需要向上转型。缺少一个就是静态绑定。

举个例子:

代码语言:javascript
复制
//基于上述的三个类
//如果确实虚函数条件,就像我们平时调用的一样,不必多说
//如果没有向上转型,比如
   quadShape* dd = new quadShape();
   dd->draw();
//输出的必然是quadShape draw,直接调用此类中的即可
//如果不是指针调用
    quadShape b;
    Shape a = (Shape)b;
    a.draw();
 //输出的也必然是shape里的draw,因为是静态绑定,什么对象调用,即执行什么类里面的函数
 
 //如果三个条件都满足虚机制(多态):
    list<Shape*> mm;
    Shape* ss = new quadShape();
    Shape* ss1 = new equalShape();
    mm.push_back(ss);
    mm.push_back(ss1);
    ss->draw();
    ss1->draw();
    cout << mm.size() << endl;
    //对于ss指针对象: new的是quadShape类,故而在第一个图的B类里产生一个指针,继而由Shape进行向上转型,
    //之后通过B类箭头后面的虚表,调用之后的B::draw()函数,也就是quadShape::draw(),从而输出的是quadShape draw
    //后面的equalShape也是一样;从而可以都push_back进list<Shape*>,实现了多态的效果。

三、this指针

this指针就是谁调用,this指针就是代表着谁。以下例子说明this的作用

代码语言:javascript
复制
//把上述Shape类里面的vfunc2()函数改为
void vfunc2(){
        cout << "设计模式Template Method" << endl;
        draw();
    }
  
 //现在在main函数里这样调用
 quadShape qs;
 qs.vfunc2();
 //结果会输出什么呢?

先卖个关子:分析一波。

  1. 因为this指针就是谁调用,this指针就是代表着谁。所以其实qs.vfunc2()等价于Shape::vfunc2(&quadShape);
  2. 在vfunc2()函数里,draw()其实也就是this->draw();(this就是quadShape的指针对象)
  3. 所以这个this是指针,并且向上转型(vfunc2是Shape里的函数)draw()也是虚函数,所以这是一个动态绑定
  4. 因此其实执行的是this所对应类里的draw;
  5. 所以输出的不是shape draw,而是quadShape draw。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、虚指针与虚表
  • 二、动态绑定与静态绑定
  • 三、this指针
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档