- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我有一种数据必须存储在一个连续的数组中,该数组被迭代以更新该数据。棘手的部分是我希望能够动态更改任何对象的更新方式。
这是我目前想出的:
struct Update {
virtual void operator()(Data & data) {}
};
struct Data {
int a, b, c;
Update * update;
};
struct SpecialBehavior : public Update {
void operator()(Data & data) override { ... }
};
然后我会为每个数据对象分配某种类型的更新。然后在更新期间所有数据都被传递给它自己的更新仿函数:
for (Data & data : all)
data->update(data);
据我所知,这被称为策略模式。
我的问题:有什么方法可以更有效地做到这一点吗?有什么方法可以在不调用虚方法的情况下实现同样的灵 active ?
最佳答案
虚函数调用的开销是多少?好吧,实现必须做两件事:
这正是两个内存间接。您可以通过将函数指针直接放在对象中(避免从对象中查找 vtable 指针)来避免两者中的一种,这是 ralismarks answer 给出的方法.
这有一个缺点,它只适用于单个虚函数,如果你添加更多,你会用函数指针膨胀你的对象,导致你的缓存压力更大,因此可能会降低性能。只要你只是替换一个虚函数,没关系,再添加三个,你的对象就膨胀了 24 个字节。
除非您确保编译器可以导出 Update
的真实类型,否则无法避免第二次内存间接寻址。在编译时。而且由于这似乎是使用虚函数在运行时执行决策的全部意义所在,因此您很不走运:任何“删除”该间接性的尝试都会产生更差的性能。
(我在引号中说“删除”,因为您当然可以避免从内存中查找函数指针。代价是您正在执行类似 switch()
或 else if()
梯形图的某些类型标识值 从对象加载,这将比仅仅从对象加载函数指针成本更高。ralismarks answer 中的第二个解决方案明确地做到了这一点,而 Vittorio Romeo 的 std::variant<>
方法隐藏了它在 std::variant<>
模板中。间接并没有真正删除,它只是隐藏在更慢的操作中。)
关于c++ - 在这种情况下是否可以避免使用虚拟方法调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43540005/
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!