tags:

views:

114

answers:

6

Just wondering, what would be fastest? If I had a base class like this

Class Base
{
virtual void Draw()
{
//something...
}
};

Then I would have an array of Base like this:

Base Array[255];

Which could contain both Base and it's derivatives. This would be one way of for example, storing various drawing commands. (I know this would seem java-like, but it's just for the example. Classes with just one function doesn't make much sense.)

Now alternatively, if I knew exactly what derivatives I would make it could be done like this

class Base
{
int ID;
};

then an array of Base like before: Base Array[255];

And then create the Draw functions in the derivatives:

class Der1 : Base
{
void Draw()
{
}
};

class Der2 : Base
{
void Draw()
{
}
};

Now, this solution of course doesn't allow me to just loop through the array and call Draw for each object. Instead it would have to be done something like this.

void CallDraw()
{
for (int i = 0; i < 255; i++)
{
switch(Array[i].ID)
{
case 1: //Der1
   ( (Der1) Array[i] ) . Draw(); 
case 2: //Der2
   ( (Der2) Array[i] ) . Draw();
}

And yeah, to those who have read so far, the actual question. Which would be faster, if you knew the derivatives? Making an organized system yourself, or using virtual functions?

And are there other things to take into consideration? (code cleanness maybe, but I rather like to show off what my class type is in the code, so I'm not bothered by the casts.

+4  A: 

Definitely use virtual functions, that's precisely what they are for. Reimplementing it yourself is error-prone and certainly isn't going to be faster.

Also, in your declaration of Array you need to use pointers:

Base *Array[255];

Otherwise, in C++ (unlike Java), the array could only contain instances of Base and no objects of derived classes. Using a pointer is more like Java's references and allows you to put instances of derived class into the array.

Greg Hewgill
And probably an array of `shared_ptr`'s or some other smart pointer, since they'll likely need to be dynamically allocated.
GMan
+2  A: 

Use virtual functions, because in logical terms they act pretty the same way, but using the virtual function table lookup, which might be slower / faster (depending on the implementation). Still, unless this is the critical part of your code (and that's 99 / 100 cases), don't bother yourself with such kinds of things.

Usage of virtual functions makes your code cleaner and you won't have to bother yourself with problems related to your own implementations of something that already exists as a part of C++.

Kotti
+1  A: 

I assume you're asking out of curiosity -- not because you would actually try to implement it with a switch.

You have to make your array Base*, not Base

A Virtual call is an array lookup and function call. A switch is often implemented as a simple constant-time jump. So, they are both O(1), but I think the virtual call would be faster since C++ compilers would be optimized to make that fast, and the switch isn't guaranteed to be O(1).

Lou Franco
A: 

Go for virtual functions. Period.

Kristian D'Amato
A: 

I would strongly argue that for cleanliness of code and maintainability that you stick to using virtual functions. There's no real reason to avoid them. They are fairly efficient at this point (languages like Java use them by default for all non-static methods). If you actually had code that had to be insanely efficient and you were trying to eke every single last instruction out of it that you could, then you'd need to write both a version with virtual functions and one without and profile it. Other than that, don't worry about it. You're trying to do what the language itself does without actually using the language's built-in way of doing it, and that's rarely a good idea. It might even be slower - only profiling would tell. Just use virtual functions and don't worry about it.

Also, Base Array[255]; is not going to work because all of your objects will get sheared and be only Base objects rather than the derived types. You need to use pointers: Base* Array[255];.

Jonathan M Davis
+1  A: 

Don’t declare an array of values of Base type: object slicing will occur and, moreover, you will lose the virtual calls.

The virtual call is “slower,” but more readable. Really, there hardly is any advantage in devirtualizing calls like that. If you’re trying to optimize your code, I bet there are better places to look at.

andref