C++中的虚函数(Virtual function)是一种用于实现运行时多态(Runtime Polymorphism)的关键技术,它允许在基类中声明一个函数为虚函数,并且在派生类中重写该虚函数。当通过基类的指针或引用调用虚函数时,程序会根据实际对象类型来动态地绑定相应的函数实现,从而实现动态多态性。具体来说,在C++中,如果希望将某个成...
在基类的func1函数中,“func2();”等价于“this-> func2();”, (调试的时候看this(或*this)的类型可能有疑惑,由于sizeof的及算方式不够动态,所以看this的地址和最初的那个引起调用的派生类对象d的地址作比较发现,this刚开始=&d;执行func2()时,this的值变化了,进入到func2()的函数体中时,this的值回到...
C/C++ 虚函数 虚(virtual)函数是为了实现多态,派生类可以覆写(override)基类的虚函数。 1、多态(polymorphism),即基类指针或者引用,可能指向基类对象,也可能指向派生类对象,会根据运行时具体指向的对象,来调用不同的函数。 2、如果没有多态,则什么类型的指针或者引用,就会调用什么类型的对象的函数。 1 2 3 4 5...
};classB :publicA {public:voidfoo(void) {//重写基类虚函数foo()cout <<"B::foo"<<endl; } };intmain(void) { A* pa =newB; pa->bar(); delete pa;return0; } 输出如下: 可以看出在bar()中调用的foo()很正常,实现了多态; 但在析构函数中调用foo(),多态机制失效了. 原因:当执行析构函数...
编译器背后和普通的非虚函数继承一样,也做了指针的偏移。 做了指针偏移,C++ 中基类对象指针调用派生类对象时,编译器通过thunk技术来实现每次参数调用和参数返回this地址的调整。 LLDB expression显示的是派生类对象的首地址(0x0000000103407f30),而不是偏移后基类对象的首地址(0x0000000103407f48),是由于LLDB调试器在ex...
基类中的虚函数允许派生类重写功能,编译器会保证派生类对象使用的是自己重写的功能,即使对象是通过基类指针访问的,例如前文中的 func(Animal *xyz) 函数,func(cat) 输出的实际上是 Cat 类重写的功能。这是一个非常有用的特性,调用者甚至都不需要知道 Cat 等派生类的实现,因为只需使用基类 Animal 指针就能够...
接下来,我们只需要把基类中的area方法声明为虚函数,那么主函数中无论Point类型的指针还是引用就都可以大胆调用,无用关心类型问题了。因为他们会依据实际指向的对象类型来决定调用谁的方法,来实现动态联编。 代码如下: 1 2 3 4 5 6 7 8 9 10 11
通过基类指针指向不同派生类对象,去调用同一个方法,可以实现多态,如下所示: Shape* shape = new CirCle(5); shape->GetArea(); 那么virtual 实现多态的底层原理是什么呢? 用C语言简单实现virtual的底层原理 用C语言模拟实现以上C++代码。首先定义一个存储函数指针的结构体VTable,作为 Shape类的虚函数表 ,其中定义...
因为派生类和基类的foo()函数具有相同的VTABLE索引,而他们的vptr又指向不同的VTABLE,因此通过这样的方法可以在运行时刻决定调用哪个foo()函数。 虽然实际情况远非这么简单,但是基本原理大致如此。 1.4 overload和override 虚函数总是在派生类中被改写,这种改写被称为“override”。我经常混淆“overload”和“override”...
在派生类有同名函数的情况下 Point * pPoint; // 声明的基类指针只能指向基类 Circle * pCircle // 声明的派生类指针只能指向派生类 如果派生类没有基类的同名函数, 派生类的指针才根据继承原则调用基类的函数 虚函数 一旦定义了虚函数, 该基类的派生类中的同名函数也自动成为虚函数. ...