开发者

difference in using virtual and not using virtual [duplicate]

This question already has answers here: Closed 12 years ago.

Possible Duplicate:

Ove开发者_如何学编程rriding vs Virtual

In C++, whether you choose to use virtual or not, you can still override the base class function. The following compiles just fine...

class Enemy 
{
public:
    void SelectAnimation();
    void RunAI();
    void Interact()
    {
        cout<<"Hi I am a regular Enemy";
    }

private:
    int m_iHitPoints;
};

class Boss : public Enemy
{
public:
    void Interact()
    {
        cout<<"Hi I am a evil Boss";
    }
};

So my question is what is the difference in using or not using the virtual function. And what is the disadvantage.


If you have the code:

Enemy * p = new Boss;
p->Interact();

and Interact is not virtual, you will get Enemy's Interact. In other words, the function will be selected based on the apparent rather than its real type of the thing it is being called on. This is almost never what you want, so if you intend to call methods via a base pointer (for example, if you have a collection of base pointers in a vector or list) then the function should be made virtual in the base class. You will also need to make the destructor of such base classes virtual, so that the behaviour when deleting instances via a base pointer is well-defined.


If Enemy::Interact() is not declared virtual, then calling Enemy::Interact() from a member function in the base class or via a pointer or reference to the base class will not call the derived class Interact() function.

For example:

Boss boss;
Enemy* bossEnemy = &boss;

boss.Interact();       // calls Boss::Interact()
bossEnemy->Interact(); // calls Enemy::Interact()

If you declare Enemy::Interact() as virtual, then Boss::Interact() will be called as you expect it to be.

The disadvantage of using virtual functions is that they are potentially more expensive to call than non-virtual functions. The disadvantage of not using virtual functions is that you probably don't get the results you want.


You tagged the question with game-development, and in such a scenario it might be hasty to disregard the extra call overhead for virtual calls: Elan Ruskin measured 50% increase in call overhead. The same guy (and many other game devs) consider it a good practice to use the added flexibility of virtual functions only when you have a concrete reason, and not just for the fun of it.

Here's a technical writeup of the reasons for the extra cost, and some musing on an extra-extra cost of pure virtual functions.


Polymorphism. Polymorphism. Polymorphism. :)

The virtual functionality is what makes C++ object-oriented. It's one of the major reasons why you are using C++ in the first place. Never think twice about using virtual if your design calls for it. Do not redesign your model simply to avoid virtuals.

Would you think twice about accessing a structure field even though there is an added cost to jump to the memory offset from the structure's base? No, of course you wouldn't if the design calls for it. Would you think twice about passing callbacks, event listeners, functors, or any other "logical" address that requires a jump to reach the actual data? Of course you wouldn't if the design calls for it.

On the flip side, there's no point to making a class member virtual if the design does not call for it, just as there's no need to pass around functors or create structs unnecessarily if the design doesn't call for it. The decision whether to use virtual is part of good OO design and implementation.

Performance

With respect to the so-called performance cost: First, this is a very old concern. The performance of the early C++ implementations of virtual calls could actually be measured without incredibly contrived code. As others have mentioned, today's technology largely obsoletes this debate.

Second, vector multiplication and similarly contrived examples are misleading. They appear to be measuring the difference between virtual calls and non-virtual calls. But they are not. They are measuring the difference between billions of virtual calls and billions of non-virtual calls to functions that do next to nothing. Is there real-world code that may be susceptible to this problem? It's certainly possible. When you find it, will the solution be to scapegoat the use of virtual in general? Clearly not. The solution is to optimize your exceptionally performance-sensitive code. As part of this hypothetical optimization, the removal of virtuals would be wise, but won't buy you much. If you've got code that performance sensitive, you'll need to optimize a heck of a lot more than discarding the virtuals.

Third, it's easily measurable, which is great, because you don't need to take our word for it. You can easily benchmark the difference with your compiler, on your target architecture, to assure yourself that there really is no performance difference.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜