Disassembly analysis: inheritance, multiple inheritance, multi-level inheritance, the essence of parent-child pointers

When talking about object-oriented languages, we can't ignore inheritance. This is also the natural advantage of object-oriented languages, which greatly improves the reuse of code. In C language, we can also achieve inheritance by nesting structures. If you look at this C++ Books, a succession can go back and forth for dozens of rounds. Let's take a look at the essence of inheritance through disassembly?

 

One: Inheritance                                    

                                        

    1. Writing without inheritance                                

   

                                     
    struct Person                                    
    {                                    
        int age;                                
        int sex;                                
    };                                    
    struct Teacher                                    
    {                                    
        int age;                                
        int sex;                                
        int level;                                
        int classId;                                
    };                                    
    struct Student                                    
    {                                    
        int age;                                
        int sex;                                
        int code;                                
        int score;                                
    };                                    
                                        
                                        
    Teacher t; observe the disassembly:                    
                                        
    t.age = 1;                  mov dword ptr [ebp-10h],1                    
    t.sex = 2;                  mov dword ptr [ebp-0Ch],2                    
    t.level = 3;                mov dword ptr [ebp-8],3                    
    t.classId = 4;              mov dword ptr [ebp-4],4                    
                                push 10h                    
    printf("%d\n",sizeof(t));                push offset string "%d\n" (0042201c)                    
                                call printf (004010e0)                    
                                add esp,8        
 
                                        
    Student s;                mov dword ptr [ebp-10h],1                    
                              mov dword ptr [ebp-0Ch],2                    
    s.age = 1;                mov dword ptr [ebp-8],3                    
    s.sex = 2;                mov dword ptr [ebp-4],4                    
    s.code = 3;               push 10h                    
    s.score = 4;              push offset string "%d\n" (0042201c)                    
                              call printf (004010e0)                    
    printf("%d\n",sizeof(s));                add esp,8    

                                    

    2. Change the way of writing:         inheritance                            

   

struct Person                                    
    {                                    
        int age;                                
        int sex;                                
    };                                    
    struct Teacher:Person                                    
    {                                    
        int level;                                
        int classId;                                
    };                                    
    struct Student:Person                                    
    {                                    
        int code;                                
        int score;                                
    };    
                                
Disassembly:                                                        
    Teacher t;                mov dword ptr [ebp-10h],1                    
                              mov dword ptr [ebp-0Ch],2                    
    t.age = 1;                mov dword ptr [ebp-8],3                    
    t.sex = 2;                mov dword ptr [ebp-4],4                    
    t.level = 3;              push 10h                    
    t.classId = 4;            push offset string "%d\n" (0042201c)                    
                             call printf (004010e0)                    
    printf("%d\n",sizeof(t));                add esp,8                    
         
             
                                        
    Student s;                mov dword ptr [ebp-10h],1                    
                              mov dword ptr [ebp-0Ch],2                    
    s.age = 1;                mov dword ptr [ebp-8],3                    
    s.sex = 2;                mov dword ptr [ebp-4],4                    
    s.code = 3;               push 10h                    
    s.score = 4;              push offset string "%d\n" (0042201c)                    
                    call printf (004010e0)                    
    printf("%d\n",sizeof(s));                add esp,8          

                                  

    Summarize:                                    

                                        

    1. What is inheritance?                                    

                                        

    Inheritance is the copying of data. From the perspective of assembly, it is exactly the same, but from the perspective of writing, it is obvious that the way of inheritance greatly improves the reuse of code.

In fact, in essence, when inheriting, that part of the inheritance code will be generated by the compiler for us instead of writing it ourselves, which is why the essence of inheritance is the copying of data, in fact, the copying of the parent class to the subclass.                                    

                                   

   2. Why use inheritance?                                                                        

    Reduce repetitive code writing                                    

                                        

    3. Person is called the parent or base class                                    

                                        

    4. Teacher and Student are called subclasses or derived classes                                    

                                        

    5. t and s can be called objects or instances.                                    

                                        

    6. You can use the parent class pointer to point to the subclass object.    

This is a core issue we want to discuss, that is, the class pointer. In fact, the above things are understood, and the class pointer is also very clear. The following code implements the parent class pointer to the child class

And it can be accessed and modified, which is actually derived from the essence of inheritance. From the perspective of memory, the inherited parent class members are placed at the beginning of the object, at the low address, the difference between the parent class pointer and the child class pointer

The most obvious is the difference in the pointer step size, and the parent class pointer points to the beginning, which happens to be a member of the parent class, which conforms to the pointer step size of the parent class, so it can just be accessed. Of course, there are not so many good things in the world

This must be due to the painstaking efforts of the language designers. So whether you can use the parent class pointer to access the subclass members is not allowed by the compiler. This is still due to the rationality of the pointer step size. Of course, from the bottom-level point of view, there is nothing that cannot be accessed. We can achieve access by some means. . Conversely, the subclass pointer accesses the parent class, which is actually of little value, because there is no member of the subclass in the parent class. And the compiler certainly doesn't allow it.

 

 




 

  


#include <iostream>
 
using namespace std ;
 
    struct Person        
    {        
        int age;    
        int sex;    
    };        
    struct Teacher:Person        
    {        
        int level;    
        int classId;    
    };        
    struct Student:Person        
    {        
        int code;    
        int score;    
    };        
            
 
    
int main (void)
{
 
    Teacher *point, t;            
    point=&t;
 
    point->age=1;
    point->classId=2;
    point->level=3;
    point->sex=4;
            
    printf("%d %d %d %d\n",t.age,t.classId,t.level,t.sex);    
    
    Person * point_test; // 父类指针
    point_test=&t; // 子类对象地址
 
    point_test->age=5;
    point_test->sex=6;
    
    printf("%d %d\n",t.age,t.sex);    
        
return 0;
}


二:      多层继承

 

多层继承比较简单,那就是你可以继承你父亲的遗产,也可以继承你爷爷的遗产。其实都可以想到,还是数据的拷贝。

                            

  










 

    多层继承:                观察反汇编:            
    1)无相同成员                            
    struct X                            
    {                 mov dword ptr [ebp-18h],1            
        int a;            mov dword ptr [ebp-14h],2            
        int b;            mov dword ptr [ebp-10h],3            
    };                 mov dword ptr [ebp-0Ch],4            
    struct Y:X            mov dword ptr [ebp-8],5            
    {                 mov dword ptr [ebp-4],6            
        int c;            push 18h            
        int d;            push offset string "%d\n" (0042201c)            
    };                 call printf (004010e0)            
    struct Z:Y                add esp,8            
    {                            
        int e;                        
        int f;                        
    };                            
                                
                                
    Z z;                            
                                
    z.a = 1;                            
    z.b = 2;                            
    z.c = 3;                            
    z.d = 4;                            
    z.e = 5;                            
    z.f = 6;                            
                                
    printf("%d\n",sizeof(z));                            
                                 
                                 
    2)有相同成员 ,二异性问题 ,但是编译器不一定会报错,默认是使用当前类的成员                                                      
                                
    struct X                            
    {                            
        int a;                        
        int b;                        
    };                            
    struct Y:X                            
    {                            
        int a;                        
        int d;                        
    };                            
    struct Z:Y                            
    {                            
        int e;                        
        int f;                        
    };                            
                                
                                
                                
    Z z;                            
                                
    z.X::a = 1;    //通过::区分了a,但是对于底层来说和上面的完全一样,
                   //这里的区分仅仅是让编译器明白。                
    z.b = 2;                            
    z.Y::a = 3;                            
    z.d = 4;                            
    z.e = 5;                            
    z.f = 6;                            
                                
    printf("%d\n",sizeof(z));                            
    printf("%d\n",z.X::a);                            
    printf("%d\n",z.b);                            
    printf("%d\n",z.Y::a);                            
    printf("%d\n",z.d);                            
    printf("%d\n",z.e);                            
    printf("%d\n",z.f);                            
 


 对于二义性问题,其本质是不存在任何问题的,从汇编看,和正常的成员完全一样,关键的就是让编译器可以区分。

三:多重继承

何为多重继承,就是有多个爹,在java 中是没有多重继承的,但是在c++中是支持多重继承的。也就是一个父类有多个子类。

 

 













   3、继承的特性        
    struct X        
    {        
        int a;    
        int b;    
    };        
    struct Y        
    {        
        int c;    
        int d;    
    };        
    struct Z:X,Y        
    {        
        int e;    
        int f;    
    };        
 

——————————————————2017年9月10日17:45:29

其实我要说的是,有时候概念多了反而不是什么好事,也许事物的本质就一种。



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325468287&siteId=291194637