C++深度探索继承

目录

 继承发生时基类可见性问题

基类子类指针转换安全性问题

总结


 继承发生时基类可见性问题

         定义Person基类,包含一个成员函数和三个不同权限限制的成员变量; 定义Student类继承该基类,且只有一个私有成员变量。

class Person{

public:
	int func() {
		return m_private;
	}
	int m_public = 1;
protected:
	int m_protect = 2;
private:
	int m_private = 3 ;
};

class Student :public Person{
private:
	int m_id = 4;
};

int main() {
	Student stu;
	return 0;
}

        查看 stu对象的分布:

         可以看到,stu 子类对象总共包含16个字节的内容,其中12字节是继承于基类的三个成员变量,4个字节是自己类内的一个成员变量。

        可以得到第一个结论:基类的可见性(权限)限制不影响子类对基类的彻底继承,可见性只不过是编译器在编译时刻做的限制。

        思考一下? 既然只是在编译时刻做的限制,那在程序跑起来的时候(运行时期),是不是可以通过指针去访问基类中 private 修饰的变量 :

        从上面的内存分布我们可以看到,stu对象的起始地址为 CB4结尾的地址,也就是从成员变量m_public 开始计算起,那么从该地址开始 + 8个字节 是不是就到了 m_private这个成员变量的地址:

int main() {

	Student stu;
	int * p = (int *)( (char *)&stu + 8 );    //强行拿到stu对象中m_private变量的地址
    
    *p = 8;       //修改m_private 变量的值 
}

        看看上述代码能否成功:

        单步走后,基类中的privte修饰的 m_private 变量真的被修改了。虽然这是一种绕过编译器限制的做法,但是可以通过此实验确定: 访问权限的检查是在编译器在 编译时期做的,而不是在运行时期。


基类子类指针转换安全性问题

        还是上个主题的代码,基类为Person ,子类为 Student :

class Person{
public:
	int func() {
		return m_private;
	}
	int m_public = 1;
protected:
	int m_protect = 2;
private:
	int m_private = 3 ;
};

class Student :public Person{
private:
	int m_id = 4;
};

        先来看看子类指针转换为父类指针的情况:

int main() {

	Student stu;

	Person *p_ptr = &stu;	//子类指针转换为父类指针

	return 0;
}

        单步走查看一下 p_ptr 的情况: 

        可以看到进行指针的转换后 ,属于正常指针转换的情况; 

        当子类指针转换为基类指针时,子类的东西会更多,因此转换为基类的时候对应的空间范围会缩小,这种情况是安全的。  --- (也就是说学生都是人  , Student 都是 Person)

        再看看父类指针转换为子类指针的情况:

int main() {

	Person per;
	Student stu;
	
	Student *s_ptr = (Student *)&per;

	return 0;
}

        单步走看看内存分布:

         原先基类对象 per 成员变量只有三个,也就是占 3* 4 = 12 个字节的空间,但我们进行强转为子类指针后,可以看到多了4个字节空间。

        从指针 s_ptr 的内存分布就可以看出来:

         这4个字节属于越界访问 ,本来Person 类只占有12个字节的空间,但是进行 基类指针强制转换为子类指针后, 会造成后面四个字节的空间也是属于基类的。(要注意,子类本来有16Byte,基类本来有12Byte)。因此这四个字节是子类的,并不是基类的。

        因此 ,基类指针转换为子类指针时 , 基类的东西可能没有子类那么多,如果子类有自己的东西的时候, 基类转换为子类时候对应的空间范围会增大,这是一种越界行为,是不安全的。--- (学生都是人 ,但不能说人都是学生 )


总结

1. 基类的可见性(权限)限制不影响子类对基类的彻底继承,可见性只不过是编译器在编译时刻做的限制。

2. 子类指针转换为基类指针是安全的 ;  基类指针转换为子类指针是不安全的。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值