【发布时间】:2012-09-22 12:42:14
【问题描述】:
我有一个关于优化虚函数调用的问题。我在某处读到过(问题是我现在找不到这篇文章),可以通过使用类似于以下的构造来优化 v-table 查找:
// 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() 时, //do something 部分将被执行,而无需查找 v-table。
这是真的还是假的?
提前感谢您的重播。
编辑:
这种结构的可能用途是限制具体实现的接口。当然,人们可以争辩说“受限”方法应该是私有的,但有时库的其他模块需要访问对象的这些公共附加方法,而不允许用户操作这些方法。因此,例如使用#defines,可以创建类似于以下的代码:
// Some.cpp
#ifdef _WIN32
Win32Concrete concrete;
#elif defined _UNIX
UnixConcrete concrete;
#endif
Base* const g_global = &concrete;
事实上,这些类的声明只能在 CPP 文件中定义,因此用户不知道它们的存在。
问题不是为什么首先要使用这种常量指针,而是在这种情况下是否可以优化 v-table 查找。
【问题讨论】:
-
这可能与编译器有关,您应该能够查看编译器生成的程序集来验证这一点
-
指针总是指向同一个对象,为什么还要使用它?
-
@BoPersson,我现在能想到一个很好的应用程序,例如跨平台库,它只向用户公开抽象接口,后端根据一些#defines 为各种平台使用多种实现.这当然需要针对具有不同定义集的每个平台进行多次编译,但对于最终用户来说仍然没有区别。
-
如果 Win32Concrete 类对 Some.h 的客户端不可见,那么他们不太可能优化 vtable,因为他们看不到它“真正是什么”,因为你不直到链接时间才决定。无论如何,不能保证 vtable 优化,所以除了一开始没有 vtable 之外,没有办法强制它。
标签: c++ optimization virtual-functions vtable