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++的动态多态性实现通用图算法使事物
对于比较不同函数调用方法的一些性能度量,请查看。它们是根据来自的函数调用的性能度量进行建模的。取决于。在真正性能关键的情况下,通常避免使用虚拟方法。对于普通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...
};