当前位置: 首页 > news >正文

南山网站建设深圳信科WordPress勾选评论

南山网站建设深圳信科,WordPress勾选评论,织梦映像,计算机类专业包括哪些文章目录 前言虚函数是什么?如何使用虚函数? 纯虚函数是什么?虚函数与普通函数的区别虚表虚表是什么?含有虚表的类内存结构图如何找到虚表的地址?示例代码代码解释 多态是什么?如何使用多态?为什…

文章目录

  • 前言
    • 虚函数是什么?
      • 如何使用虚函数?
    • 纯虚函数是什么?
    • 虚函数与普通函数的区别
    • 虚表
      • 虚表是什么?
      • 含有虚表的类内存结构图
      • 如何找到虚表的地址?
      • 示例代码
      • 代码解释
    • 多态是什么?
      • 如何使用多态?
      • 为什么要使用多态?
    • 多态遇到的所有情况
  • 总结


前言

C++ 是一种功能强大的编程语言,以其面向对象编程(OOP)特性而闻名。虚函数和多态是 C++ 面向对象编程中的两个重要概念,它们使得代码更灵活、更具扩展性。本篇文章将介绍虚函数与多态,包括其定义、使用方法及其在实际编程中的作用。


虚函数是什么?

虚函数是一种在基类中使用 virtual 关键字声明的函数,它允许在运行时通过基类指针或引用调用子类的重写版本。这种机制使得 C++ 能够实现多态性。

如何使用虚函数?

在基类中声明虚函数,并在子类中重写该虚函数。基类指针或引用可以指向子类对象,并在运行时调用子类的重写版本。

#include <iostream>class Base {
public:virtual void show() {std::cout << "Base show" << std::endl;}
};class Derived : public Base {
public:void show() override {std::cout << "Derived show" << std::endl;}
};int main() {Base* ptr = new Derived();ptr->show();  // 调用的是 Derived 的 show 方法delete ptr;return 0;
}

纯虚函数是什么?

纯虚函数是一种没有实现的虚函数,必须在派生类中实现。它使用 = 0 语法来声明。声明纯虚函数的类称为抽象类,不能直接实例化。

class AbstractBase {
public:virtual void pureVirtualFunction() = 0; // 纯虚函数
};class ConcreteDerived : public AbstractBase {
public:void pureVirtualFunction() override {std::cout << "ConcreteDerived implementation of pureVirtualFunction" << std::endl;}
};int main() {// AbstractBase obj; // 错误,不能实例化抽象类ConcreteDerived obj;obj.pureVirtualFunction(); // 调用派生类实现的纯虚函数return 0;
}

虚函数与普通函数的区别

  1. 调用时机

    • 普通函数:在编译时确定调用的函数。
    • 虚函数:在运行时确定调用的函数(动态绑定)。
  2. 多态性

    • 普通函数:不支持多态性。
    • 虚函数:支持多态性,可以通过基类指针或引用调用派生类的重写版本。

虚表

虚表是什么?

在 C++ 中,虚表(vtable)是一个由编译器维护的数据结构,用于实现虚函数的动态绑定。当一个类中包含虚函数时,编译器会为这个类创建一个虚表。虚表是一个指针数组,其中每个指针指向该类的虚函数实现。当通过基类指针或引用调用虚函数时,程序会通过虚表找到实际要调用的函数。

每个包含虚函数的类对象都有一个隐藏的指针,称为虚表指针(vptr),它指向该对象所属类的虚表。因此,通过虚表指针,程序可以在运行时动态地确定调用哪个函数。

含有虚表的类内存结构图

有下面这样的两个类:

class Base {
public:virtual void func1();int baseData;
};class Derived : public Base {
public:void func1() override;void func2();int derivedData;
};

它的内存结构图如下

+-----------------+
| Derived object  |
+-----------------+
| vptr ---------->+-------------------------+
| derivedData     |                         |
+-----------------+                         |
| baseData        |                         |
+-----------------+                         ||||+-----------------+   +-----------------+| Virtual Table   |   | Virtual Table   || for Derived     |   | for Base        |+-----------------+   +-----------------+| func1()         |   | func1()         || Derived::func1  |   | Base::func1     |+-----------------+   +-----------------+| func2()         || Derived::func2  |+-----------------+

如何找到虚表的地址?

找到虚表地址的方法涉及使用一些底层的 C++ 技巧和对内存布局的理解。以下是一个简单的示例代码,用于展示如何找到一个类对象的虚表地址并打印虚表中的内容。

示例代码

#include <iostream>class Base {
public:virtual void func1() {std::cout << "Base::func1" << std::endl;}virtual void func2() {std::cout << "Base::func2" << std::endl;}
};class Derived : public Base {
public:void func1() override {std::cout << "Derived::func1" << std::endl;}void func2() override {std::cout << "Derived::func2" << std::endl;}
};typedef void(*FuncPtr)();void printVTable(FuncPtr* vtable) {std::cout << "Virtual Table Address: " << vtable << std::endl;for (int i = 0; vtable[i] != nullptr; ++i) {std::cout << "Function " << i << " address: " << vtable[i] << std::endl;}
}int main() {Derived obj;// 获取虚表指针的地址FuncPtr* vptr = *reinterpret_cast<FuncPtr**>(&obj);printVTable(vptr);return 0;
}

代码解释

  1. 类定义

    • Base 类中定义了两个虚函数 func1func2
    • Derived 类继承自 Base 并重写了这两个虚函数。
  2. 函数指针类型

    • typedef void(*FuncPtr)(); 定义了一个函数指针类型 FuncPtr,用于指向虚函数。
  3. 打印虚表函数

    • printVTable 函数接受一个虚表指针数组并打印虚表地址和其中每个函数的地址。
  4. main 函数

    • 创建一个 Derived 类对象 obj
    • 使用 reinterpret_cast 将对象的地址转换为虚表指针数组的指针,从而获取虚表地址。
    • 调用 printVTable 函数打印虚表内容。

多态是什么?

多态性是面向对象编程的一种特性,它允许通过基类指针或引用在运行时调用不同子类的重写方法。多态性使得代码更灵活和可扩展。

如何使用多态?

通过基类指针或引用指向子类对象,并调用基类中的虚函数。在运行时,根据实际指向的对象类型调用相应的重写方法。

#include <iostream>class Animal {
public:virtual void sound() {std::cout << "Some generic animal sound" << std::endl;}
};class Dog : public Animal {
public:void sound() override {std::cout << "Bark" << std::endl;}
};class Cat : public Animal {
public:void sound() override {std::cout << "Meow" << std::endl;}
};void makeSound(Animal* animal) {animal->sound(); // 根据实际对象类型调用相应的 sound 方法
}int main() {Dog dog;Cat cat;makeSound(&dog); // 输出 BarkmakeSound(&cat); // 输出 Meowreturn 0;
}

为什么要使用多态?

  1. 代码复用:多态性允许通过统一的接口调用不同子类的方法,提高代码的复用性和可维护性。
  2. 灵活性:多态性使得程序在运行时根据实际情况调用不同的方法,提高了代码的灵活性和扩展性。
  3. 可扩展性:可以在不修改已有代码的情况下添加新的子类,并在运行时通过多态性使用它们。

多态遇到的所有情况

  1. 通过基类指针或引用调用子类方法

    • 使用基类指针或引用指向子类对象,调用虚函数实现多态性。
  2. 对象切片问题

    • 如果将子类对象赋值给基类对象,会发生对象切片问题,子类的附加属性和方法会被切掉。
    Base baseObj = derivedObj; // 对象切片,丢失 Derived 部分
    
  3. 多重继承中的多态

    • C++ 支持多重继承,可以通过虚继承解决多重继承中的菱形继承问题,使多态性依然有效。
  4. 虚析构函数

    • 在有多态的情况下,基类通常需要一个虚析构函数,以确保通过基类指针删除派生类对象时,正确调用派生类的析构函数。
    class Base {
    public:virtual ~Base() {std::cout << "Base destructor" << std::endl;}
    };class Derived : public Base {
    public:~Derived() {std::cout << "Derived destructor" << std::endl;}
    };int main() {Base* ptr = new Derived();delete ptr;  // 正确调用 Derived 的析构函数return 0;
    }
    

总结

虚函数和多态是 C++ 中面向对象编程的重要特性,通过虚函数可以实现多态性,使得代码更加灵活和可扩展。虚函数允许在运行时通过基类指针或引用调用子类的重写方法,而纯虚函数则强制派生类实现某些方法,使得抽象类无法实例化。多态性使得程序可以在运行时根据实际对象类型调用相应的方法,提升了代码的复用性、灵活性和可扩展性。然而,在使用多态时,需要注意对象切片问题和虚析构函数的使用,以确保正确的对象管理和方法调用。掌握虚函数和多态的概念和应用,对于提高 C++ 编程水平和开发效率至关重要。

http://www.yayakq.cn/news/508724/

相关文章:

  • 免费网站建设浩森宇特花都网站推广
  • 属于c2c的网站是小白网站建设教程
  • 英文网站建设 潍坊免费静态网站模板
  • 江苏百城建设有限公司官方网站嘉兴自助建站模板
  • 自己做图片的网站链接网站受到攻击怎么办
  • 公司网站建设一条定南建设银行网站点
  • 交易平台网站模板小程序的类型有哪些
  • 网站的工作简报怎么做做游乐设施模型的网站
  • 便利的网站建设青海省交通建设厅网站
  • 免费访问国外网站的app网站优化报价
  • opencms 做的网站代发推广百度首页包收录
  • 联想网站建设与分析北京网站seo优化推广
  • 网站描述模板零食网站建设描述书
  • 高端大气企业网站企业管理咨询培训
  • 个人备案的网站内容网站渗透
  • 合肥百度网站排名优化创网站需要什么
  • 阳谷网站建设网络推广苏州市建设局网站地址
  • 秦皇岛网站公司免费关键词搜索工具
  • wordpass建设网站流程学做网站的基本
  • 深圳做网站哪个公司好青岛高创网站建设
  • 怎么做淘宝卷网站做旅游网站的需求分析
  • 盘锦兴隆台住房和城乡建设网站网站建设顾问站建
  • 如何用ps做网站ui团购商城网站建设方案
  • 创业项目的网站3d视频制作公司
  • 西部数码网站管理助手ftp寿光网络推广公司
  • 福建省建设人才与科技发展中心网站网站怎么做有创意
  • 教人如何做吃的网站互联网营销师培训班
  • 番禺网站建设三杰科技淘宝客导购网站怎么建设
  • 用旧手机做网站甘肃网站建设的过程
  • 利川市网站建设浙江网站建设方案