Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 虚拟方法开销大吗?_C++_Inheritance - Fatal编程技术网

C++ 虚拟方法开销大吗?

C++ 虚拟方法开销大吗?,c++,inheritance,C++,Inheritance,我有一些复杂的继承结构,这主要是为了避免代码重复和促进各种类的公共接口。它依赖于虚拟继承和非虚拟继承,大致如下所示: class AbstractItem { //bunch of abstract methods }; class AbstractNode : virtual public AbstractItem { //some more virtual abstract methods }; class AbstractEdge : virtual public Abs

我有一些复杂的继承结构,这主要是为了避免代码重复和促进各种类的公共接口。它依赖于虚拟继承和非虚拟继承,大致如下所示:

class AbstractItem
{
   //bunch of abstract methods
};

class AbstractNode : virtual public AbstractItem
{
    //some more virtual abstract methods
};

class AbstractEdge : virtual public AbstractItem
{
    //yet some different virtual abstract methods
};
然后是一些像这样的“真正的”课程

class Item : virtual public AbstractItem
{
    //implements AbstractItem
};

class Node : public Item, public AbstractNode
{
    //implements AbstractNode
};

class Edge : public Item, public AbstractEdge
{
    //implemetns AbstractEdge
};
这被打包到一个图形模型类中,以便:

class AbstractGraph
{
    virtual QList<AbstractNode*> nodes() const = 0;
    virtual QList<AbstractEdge*> edges() const = 0;
};

class GraphModel : public AbstractGraph
{
public:
    virtual QList<AbstractNode*> nodes() const override; //this converts m_Nodes to a list of AbstractNode*
    virtual QList<AbstractEdge*> edges() const override; //dtto

private:
    QList<Node*> m_Nodes;
    QList<Edge*> m_Edge;
};
我对此有第二个想法,因为它依赖于(虚拟)继承,依赖于通过base等调用的抽象方法。由此产生的开销有那么大吗?

另一种选择是:

a) 复制粘贴大量代码以避免虚拟方法和大部分继承,但这将是代码维护的噩梦。加上没有共同的接口

b) 以某种方式将它全部模板化。。。这一点我有点不确定,甚至不知道这是否可能。为了避免代码重复,我已经在这里的一些地方使用了它们


那么,这是合理的还是过度的呢?我可以补充说,在某些情况下,我将直接调用(模型内)绕过虚拟调用,但在外部调用它通常会通过抽象基调用。

< P>尝试使用C++的动态多态性实现通用图算法使事物

  • 不必要的努力
  • 不必要的慢
  • 函数越简单,虚拟函数开销就越显著。在引用的接口中,还可以从各种函数返回容器。即使这些是COW容器,也会涉及一些工作,随意访问序列可能很容易解除(即复制)表达

    在遥远的过去(大约1990年至1996年),我曾尝试过一种基于动态多态性的图形算法的通用实现,并一直在努力解决各种问题以使其正常工作。当我第一次读到STL时,发现大多数问题都可以通过类似的抽象来解决(尽管仍然缺少一个关键思想:属性映射;有关详细信息,请参阅下面对BGL的参考)

    我发现最好用类似STL的抽象实现图形算法。算法是根据特定概念实现的函数模板,这些概念类似于基类,但有两个关键区别:

  • 抽象中不涉及虚拟函数调用,函数通常可以内联
  • 从函数返回的类型只需要对适当的概念建模,而不必通过某种形式的继承与特定接口兼容
  • 诚然,我是有偏见的,因为我写了关于这个话题的文章。对于该方法的[独立开发]应用程序,请查看


    对于比较不同函数调用方法的一些性能度量,请查看。它们是根据来自的函数调用的性能度量进行建模的。

    取决于。在真正性能关键的情况下,通常避免使用虚拟方法。对于普通PC来说,这很好。没有人能回答这个问题,因为这实际上取决于(a)您是否有需要修复的性能问题,以及(b)您的代码的哪一部分导致了这些问题。对于后者,通过探查器运行代码。我们不可能对您的需求和代码的性能发表评论,这两者都不是问题。一般来说,您应该更喜欢改进代码设计的选择,除非它们会对性能造成重大影响。可能的重复:这是一个反复出现的问题。请看:在某个开发领域花费的精力不可避免地会对其他领域产生影响。为了提高代码速度而进行不必要的优化,牺牲了在编写、测试、调试、维护和增强上花费的开发时间,这是一种总体性能损失。
    class FilterNode : public AbstractNode
    {
        //access the data in the m_Item via AbstractItem interface and implements differently AbstractNode interface
    private:
        AbstractItem *m_Item = nullptr; //this variable holds pointer to some real item with actual data such as the one from GraphModel
    };
    
    class GraphFilter : public AbstractGraph
    {
        //implements the interface differently to the GraphModel
    private:
        QList<FilterNode*> m_Nodes;
        AbstractGraph *m_Source = nullptr; //source graph...
    };