c++ || 继承 覆盖 重载

在这里插入图片描述在这里插入图片描述

面试常考

甚麽样的函数会出现重载
甚麽样的函数会出现隐藏
甚麽样的函数会出现覆盖
覆盖的函数之间会不会存在隐藏关系 覆盖关系基于隐藏关系 覆盖一定有隐藏

  1. 多态
  2. 构造函数、静态函数、析构函数能不能写成虚函数
  3. 虚函数能不能处理成内联
  4. 什么情况下析构函数必须要写成虚函数
  5. 父类指针能不能指向子类对象,子类指针能不能指向父类对象
  6. 虚函数表的产生、在那里存储

什么是RTTI,RTTI在什么时候产生
父类指针如何转化成子类指针,转化有什莫条件
什么是菱形继承?

1 多态
对于接口的不同实现方法,分为静多态和动多态,

  • 静多态是在编译时期的多态,又被称为早绑定,主要代表函数重载(函数名相同,作用域相同、返回类型相同),模板(编译时期时会根据使用的类型);
  • 动多态是在运行时期的多态,又被称为晚绑定,主要代表继承中的多态

2 构造函数、静态函数、析构函数能不能写成虚函数

  • 构造函数不能是虚函数,<1>构造函数是默认调用的,无法通过指针或者引用调用构造函数,写成虚函数无意义。<2>vfptr是在构造时写入对象,而动态调用虚函数需要用到vfptr
  • 静态函数不能声明为虚函数,静态函数不依赖于对象,静态成员函数没有this指针, 虚函数依靠vfptr和vftable来处理。vfptr是一个指针,在类的构造函数中创建生成,保存在对象中,并且只能用this指针来访问它,因为它是类的一个成员,并且vptr指向保存虚函数地址的vtable.
    对于静态成员函数,它没有this指针,所以无法访问vptr. 这就是为何static函数不能为virtual.
  • 析构函数能声明成虚函数

3 虚函数能不能处理成内联

  • 不能,虚函数需要将函数指针放到vftable,er内联函数在编译期展开,在release版本没有地址
  • 要想成为虚函数,必须要能够被取到地址(函数指针存放在vtable中,指向函数的地址),而内联函数在编译时期就已经在调用点展开,不能被取到地址所以不能是虚函数
  • 写inline virtual void f()不能保证函数f()一定是内联的,只能保证f()是虚函数(从而保证此函数一定不是内联函数)

4 什么情况下析构函数必须写成虚函数

  • 当存在父类指针指向堆上的子类对象的时候,(父类对象指向子类对象时,指向的是子类对象存储空间中父类空间开始的地方)就必须把父类的析构函数写成虚函数
    ==> 父类对象指向堆上的子类对象的时候,一定要确保父类的析构函数是虚函数

5 父类指针能不能指向子类对象,子类指针能不能指向父类对象

  • 父类指针能指向子类对象,子类指针不能指向父类对象

6 动多态的产生条件,调用过程

  • 通过引用或指针调用虚函数 +对象必须完整
    完整对象:构造函数执行完毕,析构函数还没开始
class Base
{
   
public:
	Base()
	{
   
		//this->fun();  
    //不能产生动多态 没有出构造函数直接调用虚函数 对象不完整
	}

class Derive : public Base
{
   
public:
	Derive()
	{
   
		//this->fun();
	}
	virtual ~Derive()
	{
   
		cout << "~Derive()" << endl;
	}

	virtual void fun()
	{
   
		cout << "Derive::fun()" << endl;
	}
  • 动多态调用过程

1 使用指针或者引用调用虚函数
2 在对象中找到vfptr
3 根据vfptr 找到vftable(存储虚函数指针)
4在vftable中找到要调用的函数
5 调用

7 虚函数表的产生、在那里存储

  • vftable在编译时期调用到虚函数时产生,存储在.rodata段(只读数据段)

8 类的编译顺序

  • 先编译类名->成员名(包括成员返回值、参数列表)->最后成员函数体

类与类之间的关系

  • 组合 嵌套 — 一个类中声明了另一个类
    一个类是另一个类的一部分
  • 代理 — 一个类的接口是另一个类接口的子集 一个类的功能是需要依赖另一个类的功能实现

继承

  • 继承 —
    父类:基类
    子类:派生类
    子类无法访问父类的私有成员
    外部函数只能访问类的public
    c++默认的是私有继承
    一个私有的或受保护的派生类不是子类,非公共的派生类不能做基类能做的所有的事,派生类包含着基类的对象,但是无法公开访问

继承权限:public protected private
子类继承的父类成员,在自身类中的权限不能高于继承权限

1.公有继承(public)

基类成员对派生类的可见性:
派生类来说,基类的公有成员和保护成员可见,私有成员不可见
派生类对象来说,基类的公有成员可见,其他成员不可见

公有继承时,派生类对象可以访问基类中的公有成员,派生类的成员函数可以访问基类中的公有成员和保护成员

2.私有继承(private)

基类成员对派生类的可见性:
派生类来说,基类的公有成员和保护成员可见,私有成员不可见
派生类对象来说,基类的所有成员都是不可见的

私有继承时,基类的成员只能由直接派生类访问,无法向下继承

3.保护继

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值