我有一个关于虚拟函数调用优化的问题。我已阅读的地方(而问题是,现在我无法找到文章),这可能是通过使用一个类似的结构来优化掉V-查表:虚拟函数调用的优化
// Base.h
class Base
{
public:
virtual void Foo() = 0;
};
// Concrete.h
class Concrete : public Base
{
public:
virtual void Foo()
{
// do something;
}
};
//Some.h
extern Base* const g_object;
// Some.cpp
Concrete on_stack_concrete;
Base* const g_object = &on_stack_concrete;
诀窍应该使用一个const指针指向一个在堆栈上分配的变量(不是动态的),编译器肯定会优化它。因此,无论用户何时调用g_object-> Foo(),都可以执行部分操作,而无需v-table查找。
这是真的吗?
预先感谢任何重播。
编辑:
这种构建体的可能的使用是限制具体实现的接口。当然,人们可以争辩说,“受限制”的方法应该是私有的,但有时图书馆的其他模块需要访问对象的公共附加方法,而不允许用户操纵这些方法。因此,例如使用#定义,我们可以创建类似的代码:因此
// Some.cpp
#ifdef _WIN32
Win32Concrete concrete;
#elif defined _UNIX
UnixConcrete concrete;
#endif
Base* const g_global = &concrete;
事实上这些类的声明只能在CPP文件中定义,用户不知道它们的存在。
问题不是为什么首先使用这样的常量指针,但是如果可以在这种情况下优化掉v-table查找。
这可能是编译器相关的,你应该能够验证这看你的编译器生成的程序集 – marcinj
为什么使用指针,如果它总是指向同一个对象? –
@BoPersson,我现在可以想到一个好的应用程序,例如跨平台库,仅向用户公开抽象接口,而后端根据某些#defines针对各种平台使用多个实现。这当然需要对具有不同定义集合的每个平台进行多次编译,但对于最终用户来说,这没有什么不同。 –