在查看以下简单代码时,如果我知道我们不是要从基本指针中删除,那么引入虚拟析构函数是否有意义?出于性能原因,似乎应该尽量避免对vtable进行查找。我了解过早的优化等,但这通常只是一个问题。我想知道您对以下方面的想法:


如果我们不通过基本指针删除项目,则使用受保护的析构函数
与引入单个虚拟方法相关的开销


另外,如果我的类仅具有析构函数作为虚拟方法,那么查找开销将仅用于析构函数,而其他方法将不会受到惩罚,或者一旦引入vptr,一切都会遭受损失吗?我假设每个类都在其中包含一个额外的vptr,但只需要在析构函数上执行vptr查找即可。

class CardPlayer
{
  public:
    typedef std::vector<CardPlayer> CollectionType;

    explicit CardPlayer()=default;

    explicit CardPlayer(const Card::CollectionType& cards);
    explicit CardPlayer(Card::CollectionType&& cards);

    void receiveCard(const Card& card);

    bool discardCard(Card&& card);
    void foldCards();

    inline const Card::CollectionType& getCards()  { return cards_; }
    // virtual ~CardPlayer() = default;  // should we introduce vtable if not really needed?
  protected:
    ~CardPlayer()=default;
    Card::CollectionType cards_;
};
--------------------------------------------------------------------
#include "CardPlayer.h"
#include <functional>

class BlackJackPlayer : public CardPlayer
{
  public:
    typedef std::vector<BlackJackPlayer> CollectionType;
    typedef std::function<bool(const Card::CollectionType&)> hitFnType;

  BlackJackPlayer(hitFnType fn) : hitFn_(fn) {}

  bool wantHit()
  {
    return hitFn_(getCards());
  }

  hitFnType hitFn_;
};

最佳答案

我会避免使用虚拟析构函数,因此在您的情况下将vtbl添加到类中。您可以防止通过基类指针将其删除,因此,如果没有任何其他虚拟方法,那似乎是过早的悲观了:)

同样,在大型项目中,每个实例还有一个指针(vtbl)可能会加总。性能通常取决于内存访问权限,因此您应将对象大小保持尽可能小,并且将内存访问模式保持在本地。 vtbl将位于不同的内存位置,在最坏的情况下,您要求处理器读取另一条缓存行只是为了删除对象。

要回答另一个问题:仅通过vtbl路由虚拟方法,所有非虚拟调用均不受影响。

关于c++ - 关于不同类型继承的思考,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19210894/

10-11 02:04