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");
    }
  • 相关阅读:
    软件项目管理阅读笔记02
    大二下周总结(11)
    “帮你APP”团队冲刺9
    “帮你APP”团队冲刺8
    “帮你APP”团队冲刺7
    “帮你APP”团队冲刺6
    “帮你APP”团队冲刺5
    单词统计
    “帮你APP”团队冲刺4
    “帮你APP”团队冲刺3
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5639563.html
Copyright © 2011-2022 走看看