![]() |
1
13
方法1(虚函数)
方法2(带函数指针的类)
方法3(类调用t函数)
fwiw,函数指针与函数指针不同。函数(在C++中)是用来提供函数调用的类,它通常是运算符()。 下面是一个函数示例以及一个模板函数,它使用了一个函数参数:
从性能角度来看,虚拟函数和函数指针都会导致间接函数调用(即通过寄存器),尽管虚拟函数在加载函数指针之前需要额外加载vftable指针。使用函数(带有非虚拟调用)作为回调是使用模板函数参数的最高性能方法,因为它们可以是内联的,即使不是内联的,也不会生成间接调用。 |
![]() |
2
6
方法1
方法2
方法3可能是最好的方法。它将具有最好的性能,它将是类型安全的,并且很容易理解(这是STL使用的方法)。 |
![]() |
3
5
方法2的主要问题是它根本无法扩展。考虑100个函数的等效值:
MahClass的规模已经膨胀,建造它的时间也显著增加。然而,虚函数是类大小增加的O(1) 和 构造它的时间——更不用说,用户必须手动编写所有派生类的所有回调,这些派生类将指针调整为指向派生类的指针,并且必须指定函数指针类型和混乱程度。更不用说你可能会忘记一个,或者把它设为空或者其他同样愚蠢但完全会发生的事情,因为你这样写了30个类,就像寄生黄蜂侵犯了毛虫一样侵犯了干燥。 只有当所需的回调是静态已知的时,方法3才可用。 这使得方法1成为在需要动态方法调用时唯一可用的方法。 |
![]() |
4
3
从示例中不清楚您是否创建了实用程序类。是你 回调 类的目的是实现一个闭包或一个您刚刚没有充实的更实质的对象? 第一种形式:
第二种形式:
归根结底,在我看来,第一种形式对所有正常情况都更好。第二种功能有一些有趣的功能,但不是您经常需要的功能。 |
![]() |
5
1
第一种方法的一个主要优点是它具有更高的类型安全性。第二个方法对iparam使用void*,因此编译器将无法诊断类型问题。 第二种方法的一个小优点是与C集成的工作要少一些,但是如果你的代码库仅仅是C++,那么这个优势就没有意义了。 |
![]() |
6
0
我想说,函数指针更像是C样式的。主要是因为为了使用它们,通常必须定义一个与指针定义具有相同精确签名的平面函数。 当我写C++时,我所写的唯一的平面函数是int()。其他一切都是类对象。在这两个选项中,我将选择定义一个类并重写您的虚拟机,但是如果您只想通知一些代码您的类中发生了一些操作,那么这两个选项都不是最佳解决方案。 我不知道你的确切情况,但你可能想细读一下 design patterns 我建议采用观察者模式。当我需要监视一个类或等待某种通知时,它就是我使用的。 |
![]() |
7
0
例如,让我们看一个用于添加 阅读 类的功能:
每当我想添加另一个阅读源时,我必须从类继承并添加一个特定的方法:
如果我想从文件、数据库或USB中读取,这需要另外3个独立的类。这些组合在多个对象和多个源中开始变得非常难看。 如果我使用 函数 ,恰好与 访客 设计模式:
在上述基础上,对象可以通过提供不同的读取器来从不同的源读取。
我不需要更改任何对象的代码(这是一件好事,因为它已经工作了)。我也可以将阅读器应用于其他对象。
通常,我在执行时使用继承
通用程序设计
.例如,如果我有
|
![]() |
8
0
|