笔试被鄙视之细节问题二
探讨一下派生,基类指针问题,这可是笔试原题,自己分析下会是什么结果。
 
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);
 
 
 
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号