Cpp7 C++的多态实现 — 虚表

多态的实现原理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include "stdafx.h"
#include
#include
class A
{
public:
    int x;
    virtual void Test()
    {
        printf("A \n");
    }
protected:
private:
};
class B:public A
{
public:
    int x;
    void Test()
    {
        printf("B \n");
    }
protected:
private:
};
void Fun(A* p)
{
    p->Test();
}
int main(int argc, char* argv[])
{
    A a;
    B b;
    Fun(&b);
    return 0;
}
//我们发现在这里 调用的test函数 是b的 因为fun方法传入的对象是b b继承自a 这里体现了多态
//反编译
31:   void Fun(A* p)
32:   {
00401050   push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,40h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-40h]
0040105C   mov         ecx,10h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]
33:       p->Test();
00401068   mov         eax,dword ptr [ebp+8]
0040106B   mov         edx,dword ptr [eax]
0040106D   mov         esi,esp
0040106F   mov         ecx,dword ptr [ebp+8]
00401072   call        dword ptr [edx]    //间接调用 + 虚表
00401074   cmp         esi,esp
00401076   call        __chkesp (00401240)
34:   }
@ILT+0(?Fun@@YAXPAVA@@@Z):
00401005   jmp         Fun (00401050)
@ILT+5(??0B@@QAE@XZ):
0040100A   jmp         B::B (00401190)
@ILT+10(??0A@@QAE@XZ):
0040100F   jmp         A::A (00401100)
@ILT+15(?Test@B@@UAEXXZ):
00401014   jmp         B::Test (004011f0)
@ILT+20(?Test@A@@UAEXXZ):
00401019   jmp         A::Test (00401140)
@ILT+25(_main):
0040101E   jmp         main (004010a0)

总结:

……

Cpp6 封装、继承和多态

继承

  1. 子类从父类继承成员变量
  2. 子类从父类继承成员函数
#include "stdafx.h"
class Person
{
public:
    int Age;
    int Sex;
    void Word()
    {
        printf("Person:Work");
    }
};
class Teacher:public Person
{
public:
    int Level;
};
int main()
{
    Teacher t;
    t.Age = -1; //合法但是不合理
    t.Sex = 2;
    t.Level = 3;
    return 0;
}

实现数据隐藏

为什么要隐藏数据成员

……

kali rolling 国内源

#阿里云kali源
deb http://mirrors.aliyun.com/kali kali-rolling main non-free contrib
deb-src http://mirrors.aliyun.com/kali kali-rolling main non-free contrib
deb http://mirrors.aliyun.com/kali-security kali-rolling/updates main contrib non-free
deb-src http://mirrors.aliyun.com/kali-security kali-rolling/updates main contrib non-free
#中科大kali源
deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
deb-src http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
deb http://mirrors.ustc.edu.cn/kali-security kali-current/updates main contrib non-free
deb-src http://mirrors.ustc.edu.cn/kali-security kali-current/updates main contrib non-free

Cpp5 在堆中创建对象和引用类型

我们可以在什么地方创建对象?

  1. 全局变量区

    Person p;

  2. void Max() { Person p; }

  3. newdelete

    //在堆中创建对象: Person* p = new Person(); //释放对象占用的内存 delete p;

    ……

Cpp4 类成员的访问控制

好的编程习惯 -定义和实现分开

  1. 代码会有更好的可读性
  2. 但不是必须的

在头文件中只留下声明代码

Test.h

struct sclass
{
    int x;
    int y;
    int Bigger(int x,int y);
    int Max(int x,int y,int z);
};

Test.cpp

……

Cpp3 继承

什么是继承

struct Person 
{ 
  int age; 
  int sex; 
};
struct Teacher 
{ 
  int age; 
  int sex; 
  int level; 
  int classId; 
};
struct Teacher:Person 
{ 
  int level; 
  int classId; 
};

总结:

1、什么是继承?
继承就是数据的复制
2、为什么要用继承?
减少重复代码的编写
3、Person 称为父类或者基类

……

Cpp2 构造函数和析构函数

什么是构造函数

#include "stdafx.h"
#include
struct Sclass {
    int a;
    int b;
    int c;
    int d;
    Sclass()//构造函数
    {
        printf("观察这个函数 \n");
    }
    Sclass(int a,int b,int c,int d)//构造函数
    {
        this->a=a;
        this->b=b;
        this->c=c;
        this->d=d;
        printf("观察这个函数 2\n");
    }
    int Plus()
    {
        return a+b+c+d;
    }
};
int main(int argc, char* argv[])
{
    Sclass s;
    Sclass s2(1,2,3,4);
    return 0;
}
//反汇编:
Sclass s;
0040D408   lea         ecx,[ebp-10h]
0040D40B   call        @ILT+5(Sclass::Sclass) (0040100a)
Sclass s2(1,2,3,4);
0040D770   push        4
0040D772   push        3
0040D774   push        2
0040D776   push        1
0040D778   lea         ecx,[ebp-20h]
0040D77B   call        @ILT+10(Sclass::Sclass) (0040100f)
//观察发现,分配一个对象,构造函数 方法直接就会被调用

总结特点:

……

链表

实现思想 :通过指针把要元素串起来

简单结构图

struct Student
{
    char name[10];
    int score;
}
struct Node
{
    Student Element;
    Node* next;
}

每一个节点包含此节点信息和下一个节点的指针

……

Cpp1 封装和this指针

封装

C语言和C++语言的区别

C++是对C的补充扩展,C原有的语法C++都支持,并在此基础上扩展了一些新的语法:
继承、封装、多态、模板等等

……