zoukankan      html  css  js  c++  java
  • 笔试被鄙视之细节问题二

    探讨一下派生,基类指针问题,这可是笔试原题,自己分析下会是什么结果。

    class A{

    public:
        virtual void printll()
        {
            cout<<"A::print"<<endl;
        }
    };
    class B:public A
    {
    public:
        virtual void printll()
        {
            cout<<"B::print"<<endl;
        }
    };
    class C:public B
    {
    public:
        virtual void printll()
        {
            cout<<"C::print"<<endl;
        }
    };
    void printll(A a)
    {
        a.printll();
    }
    void main()
    {
        A a,*pa,*pb,*pc;
        B b;
        C c;
        a.printll();
        b.printll();
        c.printll();

        pa=&a;
        pb=&b;
        pc=&c;
        pa->printll();
        pb->printll();
        pc->printll();

        printll(a);
        printll(b);
        printll(c);

    }

    如果全答对了,请飘过,模棱两可的还是看看下面我的分析吧。

    首先看main中第一行  A a,*pa,*pb,*pc;一定要注意pa,pb,pc都是基类A的指针。

        a.printll();                                                     A::print
        b.printll();                                                     B::print
        c.printll();这三个都是直接由ABC创建的对象,输出的结果也都必然是  C::print ,有没有人这三项结果都为C::print,这就是误认为b,c有指向子类的作用,这个作用是指针才有的,并且是基类指针指向派生类对象时才生效。

    先说下派生类内存布局,派生类对象的内存布局上首先是基类的数据,然后才是自己的数据,调用基类的函数时,如果自己重写了就调用自己的。

    再看第二问,pa,pb,pc都有了值,pa指向自身,pb指向的内存布局到b,但包含了a中的数据,pc指向的内存到c,但包含了a,b中的数据,故可得结果

    A::print

    B::print

    C::print

    再看全局函数printll(A a),参数是基类对象,如果传递的是派生类对象,那对不起了,需要把你截断了,相当于在b(以b为例)的内存布局中找到自己的数据,把多余的数据丢弃,这是C++内部的隐式转换,需要注意。这样大家也知道输出结果是什么了吧。

    最后如果我这样改动程序中两处,会是什么结果呢

    void printll(A* a)
    {
        a->printll();
    }

    printll(&a);
    printll(&b);
    printll(&c);



  • 相关阅读:
    关于测试开发及其他——写在离职之前
    牛腩新闻发布系统——初探CSS
    牛腩新闻发布系统——后台前台整合技术
    Android Audio Focus的应用(requestAudioFocus)
    正则表达式详解
    牛腩新闻发布系统——初探JQuery,AJAX
    牛腩新闻发布系统——初探Javascript
    进入中文维基百科的方法
    *args 和**kwargs 的溯源
    mathematica9激活
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3202710.html
Copyright © 2011-2022 走看看