现在我来详细讲解一下 "C++中虚函数的实现详解" 的完整攻略,包含以下内容:
1. 什么是虚函数
虚函数是C++中的一种特殊函数,可以让我们在基类中声明一个方法,在子类中对其进行重新定义,从而实现多态的特性。在实际应用中,我们通常通过将基类指针指向子类对象的方式来调用虚函数。
2. 虚函数的实现
2.1 虚函数表
C++中通过虚函数表(vtable)来实现虚函数的机制,虚函数表是一个存储虚函数指针的数组,存储在类的对象中,每一个类都分配有一个虚函数表,在其中存储了该类中的所有虚函数。
在使用虚函数时,C++使用对象的指针或引用来调用虚函数,首先会根据指针或引用中所存储的虚函数表指针来找到虚函数表,然后再根据函数在虚函数表中的位置来调用对应的虚函数。
2.2 虚函数表指针
对于每一个基类对象,在它的内存布局中都会包含一个虚函数表指针,指向基类所对应的虚函数表,在多继承的情况下,每一个包含虚函数的基类都有一个虚函数指针。在基类中,如果定义了虚函数,那么在调用虚函数时,会从基类的虚函数表中找到对应的函数,再进行调用。如果子类对虚函数进行了重写,那么会在子类的虚函数表中替换对应的虚函数指针。
3. 示例说明
示例1:调用基类和派生类中的虚函数
#include<iostream>
using namespace std;
class Base
{
public:
virtual void print(){ cout << "base class\n"; }
};
class Derived1 : public Base
{
public:
void print(){ cout << "derived class 1\n"; }
};
class Derived2 : public Base
{
public:
void print(){ cout << "derived class 2\n"; }
};
int main()
{
Base *ptr;
Derived1 d1;
Derived2 d2;
ptr = &d1;//ptr指向Derived1对象
ptr -> print();//调用派生类Derived1的虚函数print()
ptr = &d2;//ptr指向Derived2对象
ptr -> print();//调用派生类Derived2的虚函数print()
Base b;
ptr = &b;//ptr指向父类对象
ptr -> print();//调用父类中的虚函数print()
return 0;
}
输出结果为:
derived class 1
derived class 2
base class
该示例中,我们定义了一个基类 Base
,它有一个虚函数 print
,并且我们从它派生出了两个子类 Derived1
和 Derived2
,它们重写了基类的虚函数 print
。在主函数中,我们定义了一个基类指针 ptr
,并且先让它指向派生类 Derived1
的对象,再调用 ptr
的 print
函数。此时会调用派生类 Derived1
的 print
函数,输出 "derived class 1"。然后我们让 ptr
指向另一个派生类 Derived2
的对象,再次调用 ptr
的 print
函数,此时会调用派生类 Derived2
的 print
函数,输出 "derived class 2"。最后我们定义一个基类对象 b
,让 ptr
指向它,并调用 ptr
的虚函数 print
,此时会调用基类 Base
的虚函数 print
,输出 "base class"。
示例2:含有虚函数的多态类的对象布局
#include<iostream>
using namespace std;
class Point {
public:
virtual void show()
{
cout << "Point ";
}
};
class Point2D : public Point {
public:
void show()
{
cout << "Point2D ";
}
private:
int z = 0;
};
int main()
{
Point p;
Point2D p2d;
Point *ptr = &p2d;
cout << "size of Point: " << sizeof(p) << endl;
cout << "size of Point2D: " << sizeof(p2d) << endl;
cout << "size of ptr: " << sizeof(ptr) << endl;
return 0;
}
输出结果为:
size of Point: 8
size of Point2D: 16
size of ptr: 8
在该示例中,我们定义了一个虚函数 show
,它被声明为虚函数,同时从该类派生出了一个子类 Point2D
,并且重写了 show
函数。在主函数中,我们定义了一个基类对象 p
和一个派生类对象 p2d
,然后再定义一个基类指针 ptr
,并将其指向派生类对象。最后我们分别输出 p
、p2d
和 ptr
对象的大小。需要注意的是,由于各个编译器编译出来的结果可能不同,因此在具体的编译器中可能会得到不同的输出结果。在该示例中,由于 Point2D
类中新增了一个成员变量 z
,因此其大小为16字节,而 Point
类中没有新增任何成员变量,因此其大小为8字节。指向 Point
或 Point2D
类的指针都是8字节的大小,无论该指针所指向的对象是哪一个类。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c++中虚函数的实现详解 - Python技术站