zoukankan      html  css  js  c++  java
  • C++ 指针修改对象的成员变量and 多态(mooc)

    • 内存中类的对象里没有方法,只有成员变量(和结构体只有变量一样)。
      class  A
      {
          public :
              int i;
              A():i(10){}
      }
      
      void main()
      {
           A a;
           int *p = (int *) &a;  // 把对象a的地址赋值给指针p
           *p = 50;   //ok,把i的值改成50了
      }

      之所以可以通过指针修改对象里面的成员变量(即便是private 也能修改),是因为对象里只有成员变量,没有函数。则对象的地址就是第一个成员变量的地址(和结构体是一样的)

    • upcast(向上造型):子类对象会被当做父类对象看待。有一个父类A, 有一个子类B。把B的对象b 地址赋值给指针 bp ,假设A类中有一个print 函数。那么通过对象b 的指针访问ep->print();  它实际调用的却是A类的print,而不是B类的print。之前讲过一个A和B都有一个相同的函数,那么A类的函数会被隐藏。而通过指针这个则不会隐藏A的函数,而是会调用A的函数。不调用B的。
    • 多态的实现需要两个特性:upcast  和 动态绑定。动态绑定需要virtual。动态绑定:可以理解为PHP里的后期静态绑定  static::
      class A
      {
         public :
              int i;
              A():i(0){}
              ~A(){}
             virtual  void  render(){//todo} // virtual 就是让render函数和子类的相同函数产生了联系。
      }

      class B
      {
      public:
      virtual void render(){} //这里加不加virtual,都是默认有的。只要一个类的函数有virtual,那么他的子孙类中相同函数默认就都有。不过最好加上virtual,为了方便别人阅读和理解
      }
      void render(A* p) { p->render(); // 指针配合virtual 实现了 动态绑定。 }

      void main()
      {
      B b;
      render(&b); //如果没有virtual, 那么根据upcast,会调用父类A 的render函数,而现在render 有virtual 修饰,所以调用的是B类的render函数。
      //也就是实际传的是哪个对象的指针,就调用哪个一个类的函数
      }

      静态绑定:就是不带virtual,也就是正常的调用,指定哪个调用哪个。

    • 有 virtual (虚函数) 的类比正常的类大一点(内存)。所有有virtual的类的对象的头(存储对象的内存块头部)有一块内存用来存储vptr指针(这个指针是隐藏的,C++不让外面知道它的存在)。这个vptr指针指向vtable
      class  A 
      {
          public:
           int  i;
           A():i(10){}
           virtual void print() {cout << i << endl;}
      
      }
      
      void main()
      {
           cout << sizeof(a) << endl;
           A a;
          int *pa = (int *) &a;
          cout << *pa << endl;  // 输出的不是i 的值,而是vptr的值
          pa++;
          cout  << *pa  << endl;  //这时候输出的才是i 的值。得以验证对象的头不存储的是vptr 的指针。
      }

       vtable里存储的是virtual 函数的地址。vtable 是属于类的,不属于对象。所以同一个类的vtable肯定是一样的。动态绑定就是通过vtable实现的。在vtable里把virtual 函数的地址改一下就实现了动态绑定。见下图(mooc视频讲解vtable

  • 相关阅读:
    springboot 的国际化路径出现问题
    算法思想_常见四种
    数据结构_6种简单概述_java
    火狐同步和账号的区别
    java_泛型解析
    购书打折最优方案
    团队小组开发NABC分析
    环状二维数组最大子数组求和
    返回一个整数数组中最大子数组的和之测试
    首尾相连的一位数组最大子数组和
  • 原文地址:https://www.cnblogs.com/bneglect/p/14660863.html
Copyright © 2011-2022 走看看