zoukankan      html  css  js  c++  java
  • C++ 类的多态五(多态的语法本质分析)

    //多态的语法本质分析
    #include<iostream>
    using namespace std;
    
    /*
    三种易混淆的多态场景
    */
    
    class Point{
    public:
        Point(int b=0){
            this->b = b;
        }
    
        virtual void Print(){
            cout << "父类的虚函数" << endl;
        }
    
    private:
        int b;
    };
    
    class PointA :public Point{
    public:
        virtual void Print(){
            cout << "子类重写父类的虚函数" << endl;
        }
    };
    
    void ProtectB(){
        PointA pa ;
        //场景①
        Point p1;
        p1 = pa;
        p1.Print();
        //执行p1 = pa;完成的是将子类对象中父类部分的数据拷贝到父类对象中(我并不是说子类对象中有父类对象,子类对象就是子类对象,没有父类对象)
        //这个操作并没有使父类对象在内存里变成子类对象,没有分配新的内存,p1对象所占的内存空间还是那么大,只是简单的数据拷贝
        //p1.Print();他的真身是父类对象调用自己的虚函数,那么执行的还是自己的虚函数
    
        //场景②
        Point p2 = pa;
        p2.Print();
        //p2不会产生多态,因为Point p2 = pa;本质上是调用了p2的默认拷贝构造函数
        //用子类对象初始化父类对象,本质上还是将子类对象中父类部分的数据拷贝到父类对象中
        //p2在内存中的大小仍然是sizeof(Point)
        //p2.Print();他的真身是父类对象调用自己的虚函数,那么执行的还是自己的虚函数
    
        //场景③
        //但是下面的例子是完全不同的
        PointA *pa2 = new PointA();
        Point *p3 = NULL;
        p3 = pa2;
        //这里的p3 = pa2;和上面试完全的不同 pa2是一个指针,指向一个子类对象的内存空间
        //通过 p3 = pa2;   使得父类指针p3指向了子类对象的内存空间
        p3->Print();
        //此时p3->Print();会发生多态
        
    
        /*
        由此得出结论:多态的语法本质是:父类指针指向了一个子类对象(c++引用本质上是一个常量指针)
        而且我认为在多态的场景中使用父类指针加法运算是危险的
        父类的步长是sizeof(Point)个大小的字节,子类的步长是sizeof(PointA),这两个对象的步长未必相同,因为子类可能添加了自己的私有属性
        例如p3++;非常危险
        */
        delete pa2;
    
    }
    
    void main(){
        ProtectB();
        system("pause");
    }
  • 相关阅读:
    面条代码 vs. 馄沌代码
    GraphQL 到底怎么用?看看这个例子就知道了
    程序员难逃二八法则,如何晋升为头部 20% 玩家?
    正则匹配负正数和负小数
    js、Jquery处理自动计算的输入框事件
    mobile easyui兼容实体数据(tree插件为例)
    framework7中一行的字如果过多就省略号显示的CSS写法
    PHP获取系统时间不对的解决办法(转载)
    BZOJ 3156: 防御准备
    P4098 [HEOI2013]ALO
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5639563.html
Copyright © 2011-2022 走看看