c++——类 虚函数 虚基类 多态 this指针的深解

//虚基类
    //类中如果出现virtual关键字,类对象的大小多四字节,出现在继承上面叫虚继承
    //如果继承链中有虚基类,优先构造虚基类
    //如果虚基类需要带参构造,不管是直接继承还是间接继承都需要给虚基类传参
    //关键字virtual必须位于类名前,只对一个类名起作用
    class CB : public virtual CA
    class CB : virtual public CA
        void virtual run();
    virtual void run(); //都对
//多态
    //C++中的多态性具体体现在运行和编译两个方面。
    //运行时多态是动态多态,其具体引用的对象在运行时才能确定。
    //编译时多态是静态多态,在编译时就可以确定对象使用的形式。
    //同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
    //在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。

    //函数的重载不认为是多态,多态只会发生在继承关系里面   一个指令对应多种行为
        
//类中有数据是按数据类型计算大小,,若没有,有函数,一共占一个字节;
        class CM
        {
        public:
            void abc(){ printf("CM-abc"); }
            void def(){ printf("CM-def"); }
        };
        void main()
        {
            CM m;
            printf("大小%d\n", sizeof(CM));        // 1 字节, 虽然说一共有两个函数
        }
        //---------------------------------------------------------
        class CM
        {
            int a;
        public:
            void abc(){ printf("CM-abc"); }
            void def(){ printf("CM-def"); }
        };
        void main()
        {
            CM m;
            printf("大小%d\n", sizeof(CM));        // 4 字节
        }
        //---------------------------------------------------------
        class CM
        {
        public:
            void virtual abc(){ printf("CM-abc"); }
            void virtual def(){ printf("CM-def"); }
        };
        void main()
        {
            CM m;
            printf("大小%d\n", sizeof(CM));        // 4 字节 加了virtual虚函数 虚基类 4字节
        }
        //---------------------------------------------------------
        class CM
        {
            int a, b;
        public:
            CM(){ a = 10; b = 20; }
            int getA(){ return a; }
            void virtual abc(){ printf("CM-abc    %d\n", a); }
            void virtual def(){ printf("CM-def  %d\n", b); }
        };
        typedef void(*pFun)();
        int main()
        {
            pFun pf;
            CM m;
            printf("打印a %d\n", m.getA());        //a = 10;
            for (int i = 0; i < 2; ++i)
            {
                pf = (pFun)*((int *)*(int *)(&m) + i);
                pf();                            //a,b都没有初始化
            }
            printf("大小%d\n", sizeof(CM));        // 12 字节 加了virtual虚函数 虚基类 4字节
            return 0;
        }
        //类中出现了虚函数关键字,会多出4字节莫虚函数列表(函数指针数组首地址)
        //虚函数列表中放什么东西,类中的虚函数的首地址全部放进去
        //如果发生继承关系:1.基类和派生类各有各的虚函数列表(虚函数数组不继承)
        //                    2.虚函数数组元素继承
        //                    3.如果派生类给出同名元素后会发生覆盖

 

 

//虚函数:类中有虚函数,析构写成虚析构
    //虚析构可以在函数
    class CA
    {
    public: 
        CA(){ printf("CA\n"); }
        virtual ~CA(){ printf("~CA\n"); }
        void virtual run(){ printf("CA::RUN()\n"); }
    };
    class CB : public CA
    {
    public:
        CB(){ printf("CB\n"); }
        ~CB(){ printf("~CB\n"); }
        void virtual run(){ printf("CB::RUN()\n"); }
    };
    void main()
    {
        CB b;
        CA* pa;                //没有调用构造函数
        pa = &b;
        pa->run();//CB        构造顺序 CA  CB  CB::RUN  ~CB ~CA

        //另一种
        CA *pa = new CB();
        pa->run();
        delete pa;            //构造顺序 CA  CB  CB::RUN  ~CA
    }

 

posted @ 2017-10-01 21:40  千面鬼手大人  阅读(457)  评论(0编辑  收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css