Why do we need virtual and override?

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Post Reply
SuaveSteve
Posts: 80
Joined: Sat Jul 05, 2014 7:38 am

Why do we need virtual and override?

Post by SuaveSteve »

I'm struggling to see what the point of virtual and override is when inheritance works without them. Both these snippets do the same thing:

Code: Select all


class A {

	void doThing() { 
        Console.printf("A");
    }

}


class B : A {

	void doThing() {
		Console.printf("B");
		super.doThing();
	}

}

Code: Select all


class A {

	virtual void doThing() { Console.printf("A"); }

}


class B : A {

	override void doThing() {
		Console.printf("B");
		super.doThing();
	}

}

User avatar
phantombeta
Posts: 2195
Joined: Thu May 02, 2013 1:27 am
Operating System Version (Optional): Windows 10
Graphics Processor: nVidia with Vulkan support
Location: Brazil

Re: Why do we need virtual and override?

Post by phantombeta »

These snippets don't do the same thing.
In the first snippet, you're shadowing the "doThing" function from A in B. Anything calling "doThing" with a pointer of type A will call A's version of doThing, even if the pointer points to an instance of B.
In the second snippet, you're actually overriding A's "doThing" function, and calling doThing with a pointer of type A will call the correct function if overridden.

As an example, try these two snippets:

Code: Select all

class Foo : Actor {
    override void PostBeginPlay () {
        asd ();
    }

    void asd () {
        Console.Printf ("aaa");
    }
}

class Bar : Foo {
    void asd () {
        Console.Printf ("bbb");
    }
}

Code: Select all

class Foo : Actor {
    override void PostBeginPlay () {
        asd ();
    }

    virtual void asd () {
        Console.Printf ("aaa");
    }
}

class Bar : Foo {
    override void asd () {
        Console.Printf ("bbb");
    }
}
Spawn "Foo", then spawn "Bar". With the first snippet, you'll get "aaa" with both, while with the second snippet, you'll get "aaa" when spawning Foo and "bbb" when spawning Bar.
SuaveSteve
Posts: 80
Joined: Sat Jul 05, 2014 7:38 am

Re: Why do we need virtual and override?

Post by SuaveSteve »

I see. Am I correct in saying that ZScript went the route of C++ by having functions non-virtual by default instead of Java where they're virtual by default? And how is that useful?
User avatar
Chris
Posts: 2983
Joined: Thu Jul 17, 2003 12:07 am
Graphics Processor: ATI/AMD with Vulkan/Metal Support

Re: Why do we need virtual and override?

Post by Chris »

SuaveSteve wrote:I see. Am I correct in saying that ZScript went the route of C++ by having functions non-virtual by default instead of Java where they're virtual by default? And how is that useful?
Less overhead. A non-virtual member function is essentially just a normal function with an implicit 'this' pointer. It's invoked directly. A virtual member function is a function pointer in a vtable, which requires indirect memory accesses (and as minor as a memory access may be, they can very quickly add up, especially if it's hitting "cold" memory that's not in the cpu's cache).
dpJudas
 
 
Posts: 3177
Joined: Sat May 28, 2016 1:01 pm

Re: Why do we need virtual and override?

Post by dpJudas »

It isn't just the saved memory access. When the function isn't virtual the compiler can inline more functions (*). A virtual function can't be inlined unless the compiler can determine that the object reference cannot possibly be a derived version of the class.

*) The compiler doesn't actually inline any functions right now, but that's besides the point.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49252
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Why do we need virtual and override?

Post by Graf Zahl »

Another point is programming safety. A virtual function can be overridden by a child class at will and you lose all control over the program flow because users can hook themselves into code they are not supposed to touch.

It's not as bad as Objective-C, though, where a program can replace any method at run time and wreak havoc. Virtual by default is fundamentally unsafe and mostly found in academic languages that unfortunately found their way into production environments.
Post Reply

Return to “Scripting”