网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
原理:将虚基类对现象放到公共位置(vs是放到整个对象尾部),虚基表中存偏移量,来计算虚基类的位置;
没加virtual之前
加了virtual只后的内存情况
虚继承中,将A通常叫做虚基类
虚函数
概念:虚函数重写是多态条件之一
多态原理:虚函数地址放到对象的虚表(虚函数表)中,多态指向谁调用本质是运行到对象虚表找到要调用的虚函数
析构函数可以是虚函数吗?什么场景下析构函数是虚函数?
答:可以,并且最好把基类的析构函数定义成虚函数
总结:虚函数虚基类两个地方都用到virtual关键字,它们之间没有一点关联,不要联系到一起。
重写(覆盖)
满足重写,必须接口一致,并且是虚函数继承,重写虚函数的继承是一种接口继承,什么是接口继承呢?
以下程序输出结果是() :
class A
{
public:
virtual void func(int val = 1){ std::cout<<"A->"<< val <<std::endl;}
virtual void test()//void test(A*this)
{
func();//this->func()
}
};
class B : public A
{
public:
void func(int val=0){ std::cout<<"B->"<< val <<std::endl; }
};
int main(int argc ,char* argv[])
{
B*p = new B;
p->test();//p->test(p)
return 0;
}
输出:B->1;重写,只会重写函数的实现,不对(int val=0)中的val=0干扰,可以是
void func(int a)
或void fun(int)
都会构成重写,所以val的值还是对象A的val
总结:子类的缺省参数不起作用,重写虚函数是一种接口继承,也就可以理解成函数、返回值、参数(包括缺省参数)都是父类继承下来,所以这里用的 父类的缺省参数
隐藏
( 1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无 virtual
关键字,基类的函数将被隐藏(注意别与重载混淆)。
( 2)如果派生类的函数与基类的函数同名, 并且参数也相同, 但是基类函数没有 virtual
关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。
示例程序中:
#include <iostream.h>
class Base
{
public:
virtual void f(float x){ cout << "Base::f(float) " << x << endl; }
void g(float x){ cout << "Base::g(float) " << x << endl; }
void h(float x){ cout << "Base::h(float) " << x << endl; }
};
class Derived : public Base
{
public:
virtual void f(float x){ cout << "Derived::f(float) " << x << endl; }
void g(int x){ cout << "Derived::g(int) " << x << endl; }
void h(float x){ cout << "Derived::h(float) " << x << endl; }
};
( 1)函数 Derived::f(float)覆盖了 Base::f(float)。
( 2)函数 Derived::g(int)隐藏了 Base::g(float),而不是重载。
( 3)函数 Derived::h(float)隐藏了 Base::h(float),而不是覆盖。
多态
1、虚函数的重写 2、父类的指针或引用调用才符合多态条件
多态是在运行时到指向对象的虚表中查找要调用的虚函数的地址来进行调用,如果没加*或&,就会在编译时直接确认类型调用函数的地址
纯虚函数
//virtual void fun(){}//虚函数
virtual void fun() = 0;//纯虚函数
包含纯虚函数的类叫抽象类,抽象类不能实例化出对象
纯虚函数的作用:
1、强制子类去完成重写:父类的纯虚函数virtual void fun() = 0;
子类重写:virtual void func(){}
2、表示抽象的类型,抽象就是在现实中没有对应的实体的。
虚函数表
在32位平台下,没有加virtual大小为1,加了之后就会变4,这是因为加了虚函数关键字,底层会有个vftptr(vitual function table pointer)虚函数表指针;
1、虚函数存在哪?
答:代码段
2、虚函数表(虚表)存在哪?
代码段(常量区)
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
15)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新