文章目录
面试常考
甚麽样的函数会出现重载
甚麽样的函数会出现隐藏
甚麽样的函数会出现覆盖
覆盖的函数之间会不会存在隐藏关系 覆盖关系基于隐藏关系 覆盖一定有隐藏
- 多态
- 构造函数、静态函数、析构函数能不能写成虚函数
- 虚函数能不能处理成内联
- 什么情况下析构函数必须要写成虚函数
- 父类指针能不能指向子类对象,子类指针能不能指向父类对象
- 虚函数表的产生、在那里存储
什么是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)
基类成员对派生类的可见性:
对派生类来说,基类的公有成员和保护成员可见,私有成员不可见
对派生类对象来说,基类的所有成员都是不可见的
私有继承时,基类的成员只能由直接派生类访问,无法向下继承