在查看以下简单代码时,如果我知道我们不是要从基本指针中删除,那么引入虚拟析构函数是否有意义?出于性能原因,似乎应该尽量避免对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/