【问题标题】:C++: Template method pattern using directly the derived typeC++:直接使用派生类型的模板方法模式
【发布时间】:2016-02-03 18:30:39
【问题描述】:

假设情况:

struct base
{
    void method()
    {
        requisites();

        do_it();
    }

    virtual void requisites() const = 0;
    void do_it() { /* do it */ }
};

struct derived : base
{
    void requisites() const
    {
        if (!my_requisites)
           throw something;
    }
}

int main()
{
    derived d;
    d.method();

    return 0;
}

在这种情况下,我不使用指针或引用,而是直接使用派生类型的实例,编译器是否需要对 vtable 进行运行时查询以选择正确的 requisites 覆盖( derived) 之一?还是这种行为与不使用虚函数一样有效?换句话说,编译器是否在编译时知道我们正在使用derived::requisites()

【问题讨论】:

  • 这在很大程度上取决于您使用的编译器。有些编译器很聪明,会说:“嘿,整个项目中只有一个类派生自基类,所以让我们干掉 vtable”。
  • 这个问题和策略模式有什么关系?
  • @ChristianHackl 对不起,你是对的。无论如何,这将是一个“模板方法”模式。你又是对的,这个问题不是与“设计模式”相关的问题(尽管这里使用模式作为问题的上下文)

标签: c++ derived-class virtual-functions vtable


【解决方案1】:

vtable 不一定慢。

例如,在 x86 上的 unix 共享对象中,已使用 hack 生成与位置无关的代码 (gcc3, gcc4),以使用当前 eip 加载 ebx。该值用于查找任何静态函数的跳转表。可以通过直接查询this 指针来调用动态函数,并且速度更快(如果在给定函数中没有调用静态函数)。

编译器确实知道具体类型,可以直接调用函数,但可能会选择虚拟查找函数,因为:-

a) 它可能会更快。

b) 它简化了代码生成案例的数量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-17
    • 2014-03-22
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    相关资源
    最近更新 更多