详解C++虚成员函数和动态联编

推荐学习: 《c++教程》

——编译器对非虚方法使用静态联编(编译时匹配),对虚方法使用动态联编(运行时匹配)。

未使用虚方法时,指针类型在编译时已知,因此编译器在编译时,可以将成员方法关联到相应的类,这被称为静态联编;使用虚方法时,通常只有在运行程序时才能确定对象类型,所以编译器生成的代码在程序执行时将成员函数关联到相应的类,这被称为动态联编。

  静态联编比动态联编效率高。

  虚函数的工作原理。

  虚函数。

  重新定义成员函数(改变函数特征标)。

立即学习“C++免费学习笔记(深入)”;

  重新定义重载的成员函数。

  效率

  为使程序能够在运行阶段进行决策,必须采取一些方法来跟踪基类指针或引用指向的对象类型,这增加了额外的处理开销。因此下列情况更适合静态联编:

类不会用作基类派生类不重新定义基类的任何方法

  因此静态联编被设置为C++的默认选择。

  如果要在派生类中重新定义基类的方法,则将它设置为虚方法;否则设置为非虚方法。

  虚函数的工作原理

  编译器处理虚函数的方法是:给每个对象添加一个隐藏成员。隐藏成员中保存了一个指向·函数地址·数组的指针。这种数组被称为虚函数表(vtbl),表中存储了为类对象进行声明的虚函数的地址。

  派生类对象将包含一个指向独立地址表的指针(即新创建一个表)。(增加内存开销)

  调用虚函数时,程序将查看存储在对象中的vtbl地址,然后转向相应的函数地址表并在表中查找地址。(影响执行速度)

  总之,使用虚函数将在内存和执行速度上有一定的成本;即使非函数的效率比虚函数稍高,却不具备动态联编功能。

  构造函数不能是虚函数。

  析构函数应当是虚函数,除非类不用做基类。

  友元函数不能是虚函数,因为友元不是类成员,而只有成员才可以是虚函数。

  如果派生类没有重新定义函数,将使用该函数的基类版本(继承它)。如果派生类位于派生链中,则将使用最新的虚函数版本(指针或引用调用),基类版本被隐藏的情况除外。

   重新定义将隐藏基类方法:

class Dwelling{public:    virtual void showperks(int a) const;    ...};class Hovel : public Dwelling{public:    virtual void showperks() const;    ...}

登录后复制

  在派生类中重新定义函数(改变了参数特征标),将隐藏同名的基类方法,而不是重载基类方法。

Hovel trump;trump.showperks();    // validtrump.showperks(5);    // invalid

登录后复制

  如果重新定义继承的方法,应确保与原来的原型完全相同。如果返回类型为基类引用或指针,则可以修改为指向派生类的引用或指针(返回类型协变:即允许返回类型随类类型的变化而变化)。

  如果基类声明被重载了,则应在派生类中重新定义所有的基类版本;如果只定义了一个版本,则其它版本将被隐藏,派生类对象将无法使用它们。

class Dwelling{public:    virtual void showperks(int a) const;    virtual void showperks(double x) const;    virtual void showperks() const;    ...};class Hovel : public Dwelling{    virtual void showperks(int a) const;    virtual void showperks(double x) const;    virtual void showperks() const;    ...};

登录后复制

   如果不需要修改,则新定义可只调用基类版本:

  void Hovel::showperks()const {Dwelling::showperks();} 

以上就是详解C++虚成员函数和动态联编的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2492427.html

(0)
上一篇 2025年3月5日 01:09:48
下一篇 2025年2月25日 10:06:25

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • c语言如何统计字符串中每个字符出现的次数?

    c语言统计字符串中每个字符出现的次数的方法:首先下载安装winTC并打开;然后快捷键【ctrl+N】新建文件,并输入代码;最后保存文件,并输入要统计的字符串后按enter键即可。 c语言统计字符串中每个字符出现的次数的方法: 1、下载安装w…

    2025年3月5日
    200
  • c++如何获取系统时间?

    c++kquote>c++获取系统时间的方法:1、使用系统函数,并且可以修改系统时间;2、获取系统时间,代码为【time_t now_time=time(NULL)】;3、使用windows API ,精确到毫秒级。 c++获取系统时…

    2025年3月5日 编程技术
    200
  • C语言中二叉树中序遍历怎么执行?

    C语言中二叉树中序遍历的方法:首先遍历左子树,并借助递归继续访问直到最左侧节点;然后访问根结点;最后遍历右子树,并借助递归继续访问直到最右侧节点即可。 C语言中二叉树中序遍历的方法: 中序遍历的规则是:左子树—> 根结点 …

    2025年3月5日
    200
  • C语言中 gets 和 getchar 区别?

    gets和getchar区别:gets函数是输入一行字符串,以回车结束,并且回车键会被过滤掉,不会被读到字符串中,而getchar函数是读取一个字符,包括回车键也会被读成一个字符。 函数原型: char * gets(char * ptr)…

    2025年3月5日
    200
  • c++贪吃蛇代码是什么

    c++贪吃蛇代码是【snake_position position[(N-2)*(N-2)+1],void snake_position::initialize(int &j),{x = 1;y = j;}char s[N][N]】…

    2025年3月5日
    200
  • c++清屏函数是什么

    c++kquote>c++清屏函数是“system(“cls”)”。system()是一个C/C++的函数,功能是发出一个DOS命令;当该函数的参数为“cls”时,表示在DOS上使用cls命令,作用是“清屏”,…

    2025年3月5日
    200
  • C++类型如何进行转换

    方法:1、static_cast,用于非多态类型的转换;2、reinterpret_cast,转换成另一种不相关类型;3、const_cast,删除变量的const属性,再赋值;4、dynamic_cast,用于类继承层次间指针或引用转换。…

    2025年3月5日 编程技术
    200
  • C#中如何使用LINQ查询数据

    C#中如何使用LINQ查询数据,需要具体代码示例 LINQ(Language Integrated Query)是C#中的一种强大的查询语言,它可以帮助开发者简化对数据的查询和操作。本文将介绍如何在C#中使用LINQ查询数据,并提供具体的代…

    2025年3月5日
    200
  • C#开发中如何处理跨域请求和安全性问题

    C#开发中如何处理跨域请求和安全性问题 在现代的网络应用开发中,跨域请求和安全性问题是开发人员经常面临的挑战。为了提供更好的用户体验和功能,应用程序经常需要与其他域或服务器进行交互。然而,浏览器的同源策略导致了这些跨域请求被阻止,因此需要采…

    2025年3月5日
    200
  • C#中如何使用权限控制和身份验证

    C#中如何使用权限控制和身份验证,需要具体代码示例 在当今互联网时代,信息安全问题受到了越来越高的重视。为了保护系统和数据的安全,权限控制和身份验证成为了开发者必不可少的一部分。C#作为一种常用的编程语言,提供了丰富的功能和类库来帮助我们实…

    2025年3月5日
    200

发表回复

登录后才能评论