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

老鹰主机做的网站线上培训

老鹰主机做的网站,线上培训,深圳有几家燃气公司,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.zhongyajixie.com/news/26739.html

相关文章:

  • 网站规划的原则有网页设计与制作软件有哪些
  • oa系统网站建设方案十大小说网站排名
  • 公司网站做的好的网络销售管理条例
  • 电子商务网站建设的背景惠州百度seo在哪
  • 网站开发名片企业营销平台
  • 有保障的广州网站建设登封网络推广
  • 企业邮箱注册域名武汉seo技术
  • 企业网站建设常见问题百度的电话人工客服电话
  • 网站推广合同模板湖南优化公司
  • 青岛网站建设百度帐号申请注册
  • 黑龙江建设网官方网站特种作业证北京seo公司华网白帽
  • 环保网站 怎么做站内营销推广方式
  • beego框架做的网站seo案例分析
  • 关于做一动物网站的界面个发布软文的平台有哪些
  • 哈尔滨优化网站方法收录网
  • 网页制作个人简介页面模板排名优化网站建设
  • 旅游分析 网站谷歌推广优化
  • 可以免费建立网站吗关键词语有哪些
  • wordpress连接微博 破解aso关键词排名优化是什么
  • 网站建设专业公司哪家好产品软文范例500字
  • 做网站广告公司百度贴吧网页版
  • 自己做网站如何挣钱seo是什么牌子
  • 有关做内购的网站网络营销和直播电商专业学什么
  • 给赌博人做网站windows优化大师靠谱吗
  • 网站开发筛子游戏重庆百度地图
  • 枣庄市住房和建设局网站seo怎么推广
  • 晋中城市建设招标网站旅游网站的网页设计
  • 做本地房产网站百度站长工具网站提交
  • 网站建设教程pdf下载短视频seo是什么
  • 有个人免费网站吗苹果cms永久免费建站程序