C++ 继承

本文通过C++代码和汇编分析,深入探讨了继承的内存模型,解释了如何通过继承解决代码重复问题,并讨论了私有、保护和公共继承的差异。同时,文章阐述了权限与继承的关系,以及父类指针操作子类对象的安全性,明确了构造和析构函数的执行顺序。最后,文章通过实例解析了名称隐藏的概念及其作用,以防止重载函数导致的二义性问题。
摘要由CSDN通过智能技术生成

对于继承,我们先不说概念。下面我还是先用C模拟并借助汇编的方式来理解它,侧重于学习继承的内存模型。

我们先来看代码,设计三个类,People类,Teacher类,Student类

struct Person		
{		
	int age; //年龄	
	int sex; //性别	
};		
struct Teacher		
{		
	int age; //年龄	
	int sex; //性别
	int level;//教师等级	
};		
struct Student		
{		
	int age; //年龄	
	int sex; //性别		
	int score;//分数	
};

OK,下面分别创建对应的对象进行赋值

void createPerson()
{
    Person person;
    person.age = 20;
    person.sex = 1;
}

void createTeacher()
{
    Teacher teacher;
    teacher.age = 20;
    teacher.sex = 1;
    teacher.level = 3;
}	

void createStudent()
{
    Student student;
    student.age = 20;
    student.sex = 1;
    student.score = 60;
}

写完代码,其实就可以发现,太多的重复了,那如何解决呢,别着急,我们来画一下这几个类的内存模型,我们如何知道其内存如何排放呢,其实只要调试起来,在内存窗口观察变化即可。

在这内存模型中我们也可以发现,其实这三个类的前面部分内存都是一样的,也就是绿,蓝,黄 三部分,下面我们再通过汇编来验证下

26:       Person person;
27:       person.age = 20;
00401048 C7 45 F8 14 00 00 00 mov         dword ptr [ebp-8],14h ;age 也是person首地址 
28:       person.sex = 1;
0040104F C7 45 FC 01 00 00 00 mov         dword ptr [ebp-4],1 ;sex


33:       Teacher teacher;
34:       teacher.age = 20;
00401078 C7 45 F4 14 00 00 00 mov         dword ptr [ebp-0Ch],14h ;age 也是teacher首地址
35:       teacher.sex = 1;
0040107F C7 45 F8 01 00 00 00 mov         dword ptr [ebp-8],1 ;sex
36:       teacher.level = 3;
00401086 C7 45 FC 03 00 00 00 mov         dword ptr [ebp-4],3 ;level


41:       Student student;
42:       student.age = 20;
004010B8 C7 45 F4 14 00 00 00 mov         dword ptr [ebp-0Ch],14h ;age 也是student首地址
43:       student.sex = 1;
004010BF C7 45 F8 01 00 00 00 mov         dword ptr [ebp-8],1 ;sex
44:       student.score = 60;
004010C6 C7 45 FC 3C 00 00 00 mov         dword ptr [ebp-4],3Ch ;score

这里因为对于的结构体的大小不一样,所以在分配空间时,其对应的对象首地址肯定也不一样。但是从汇编上分配的大小和顺序也能看出,其前面的部分内存其实是一样的。

那么既然一样,我们能不能去掉重复呢,想想之前的所学知识,我们是不是可以使用包含解决,动手试试

struct Person		
{		
	int age; //年龄	
	int sex; //性别	
};		
struct Teacher		
{		
	Person person;
	int level;//教师等级	
};		
struct Student		
{		
	Person person;	
	int score;//分数	
};

在Teacher类和Student类中分别包含Person类,好像重复问题解决了。而且内存模型也是和之前一样的,你可以想象下直接将Person的内存模型往右边的Teacher类和Student类复制。

但是,此时你会发现新问题又来了,那就是给对象赋值需要发生变化

void createPerson()
{
    Person person;
    person.age = 20;
    person.sex = 1;
}

void createTeacher()
{
    Teacher teacher;
    teacher.person.age = 20;
    teacher.person.sex = 1;
    teacher.level = 3;
}	

void createStudent()
{
    Student student;
    student.person.age = 20;
    student.person.sex = 1;
    student.score = 60;
}

前面说了其内存模型不变,既然内存模型不变,那么虽然赋值代码发生了变化,汇编代码应该还是一样的吧,我们来看一下汇编代码。

24:       Person
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值