c++中虚函数的实现详解

现在我来详细讲解一下 "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,并且我们从它派生出了两个子类 Derived1Derived2,它们重写了基类的虚函数 print。在主函数中,我们定义了一个基类指针 ptr,并且先让它指向派生类 Derived1 的对象,再调用 ptrprint 函数。此时会调用派生类 Derived1print 函数,输出 "derived class 1"。然后我们让 ptr 指向另一个派生类 Derived2 的对象,再次调用 ptrprint 函数,此时会调用派生类 Derived2print 函数,输出 "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,并将其指向派生类对象。最后我们分别输出 pp2dptr 对象的大小。需要注意的是,由于各个编译器编译出来的结果可能不同,因此在具体的编译器中可能会得到不同的输出结果。在该示例中,由于 Point2D 类中新增了一个成员变量 z,因此其大小为16字节,而 Point 类中没有新增任何成员变量,因此其大小为8字节。指向 PointPoint2D 类的指针都是8字节的大小,无论该指针所指向的对象是哪一个类。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c++中虚函数的实现详解 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • 解析C/C++ Capstone 引擎源码编译问题

    解析C/C++ Capstone 引擎源码编译问题的完整攻略如下: 准备工作 首先需要确保本地安装了以下软件: cmake:用于跨平台的自动化构建工具,能够自动化生成工程文件。 GNU make:用于自动化构建过程中的编译操作,是一个常用的自动化构建工具。 gcc:C++编译器。 安装完毕后,可以通过以下命令验证是否完成安装: cmake –version…

    C 2023年5月23日
    00
  • C语言求字符串长度的四种方法实例代码

    下面是针对“C语言求字符串长度的四种方法实例代码”这个主题的完整攻略: 一、背景 在C语言中,获取字符串长度是一个比较基础的操作,它在很多情况下都非常有用。本文将介绍四种常见的C语言获取字符串长度的方法,逐一进行讲解和实例演示。 二、方法一:使用strlen()函数 strlen()函数是C语言中用于获取字符串长度的标准函数,它的使用非常简单,直接传入字符串…

    C 2023年5月24日
    00
  • iOS Runtime详解(新手也看得懂)

    iOS Runtime详解(新手也看得懂) 什么是Runtime? Runtime是指在运行时进行操作的能力。在iOS开发中,Runtime是一种基于C语言的API,它可以动态地创建类、对象和修改类的属性和方法等。其主要的作用是在编译阶段之外,给我们提供了对类和对象的管理。 Runtime的应用场景 动态给类添加属性(associative referenc…

    C 2023年5月22日
    00
  • C语言小项目计时器的实现思路(倒计时+报警提示)

    C语言小项目计时器的实现思路(倒计时+报警提示) 思路概括 计时器的实现思路可以分为三个部分: 用户输入倒计时的时间,程序将其保存下来。 程序不断地循环检查当前时间与开始时间之间的差值是否大于等于用户设定的时间,当差值达到要求时,触发报警提示。 用户可以选择中途取消倒计时。 具体实现 1. 用户输入倒计时的时间 用户需输入倒计时的时间,可以通过scanf函数…

    C 2023年5月23日
    00
  • C++实现职工信息管理系统

    C++实现职工信息管理系统 介绍 C++实现职工信息管理系统是一个简单的控制台应用程序,用于管理一个公司中的职工信息。主要的功能包括添加职工、显示职工列表、删除职工、修改职工信息等。 实现步骤 步骤一:设计职工信息类 我们首先需要设计一个职工信息类,它包括职工编号、职工姓名、职工职位和职工性别等信息。这个类可以使用C++中的结构体来实现。 // 职工信息结构…

    C 2023年5月23日
    00
  • 五个嵌入式C语言中的实用技巧分享

    下面是“五个嵌入式C语言中的实用技巧分享”的完整攻略: 1. 利用位运算提高效率 位运算是嵌入式开发中非常常见的操作,因为它可以大幅提高程序效率。以下是一些常见的位运算技巧: (1) 判断奇偶性 使用&运算符可以判断一个数是奇数还是偶数,比如: int x = 13; if (x & 1) { printf("x是奇数\n&quot…

    C 2023年5月23日
    00
  • C程序 检查字符串是否为Pangram

    下面就为您详细讲解“C程序 检查字符串是否为Pangram”的完整使用攻略: 什么是Pangram Pangram是一个包含所有字母的字符串。 这意味着,很多时候我们需要检查某个字符串是否为Pangram。 接下来我们就来学习如何使用C程序来检查字符串是否为Pangram。 程序代码 以下是C语言程序来检查字符串是否为Pangram的代码: #include…

    C 2023年5月9日
    00
  • C语言实现socket简单通信实例

    下面我将为你讲解“C语言实现socket简单通信实例”的完整攻略。 1. 什么是Socket? Socket(套接字)是计算机网络中对TCP/IP协议的抽象,是一组接口和规范,用于实现网络通信或者进程间通信。利用Socket,程序员可以方便的开发出网络应用程序,实现进程之间的网络通信和资源共享。 2. C语言实现Socket通信要点 在C语言中,我们可以通过…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部