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");
    }
  • 相关阅读:
    UVA 12546 LCM Pair Sum
    两两间的距离都是整数的点集
    Codeforces 11.27
    Codeforces 11.27 B
    UVA 105
    打印自身的程序
    Interval DP
    Tree DP
    参加第五次全国工程建设行业信息化建设高峰论坛 (个人的一点感想)
    基础资料分类及清单版本管理
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5639563.html
Copyright © 2011-2022 走看看