Virtual/Override and Inheritance

I have researched virtual/Override and Inheritance i have some basic knowledge on them but i felt like i needed to know more so from my research i have learn what they all mean and i am just looking for someone to read through this and correct me on anything and add any extra information i have missed.

If you dont know what virtual/Override and Inheritance is i wouldn’t advice trying to learn what they are from this as i could be completely wrong.

Inheritance - What i have gathered from this is that I created a class from the type actor and then called it a “WeaponBase” and inside of this i have the code to create a SkeletalMesh as you can only inherit things that are public or protected i added the .h code to public. When i go to make a child actor of my base class i go to “all classes” and find the class WeaponBase and make a child class of the that class since its a child class everything that is public/protected inside the WeaponBase class will be inherited by all the child classes which means that inside the child class it will also have the SkeletalMesh But as its inherited from the WeaponBase class you wont see the code in the child class.

Virtual - From researching virtual i have learnt that the word Virtual is used in front of the functions that are declared in the .h file and virtual basically says to the class that all child class of that class can access that function.


Override - I have made a flow chart to show what i mean. As you can see from the flow chart inside of the “WeaponBase” class i have a function called OnFire(); as this would be virtual as i am making a child class from the Base class using the same function name. Inside of the child class “WeaponRifle” i have a function called the same “OnFire();” because the Base class and the child class both have the same function name “OnFire();” i would use the word Override at the end so its saying to the class look up through the Inheritance Hierarchy in this case it would be Actor->WeaponBase->WeaponRifle so the override word says go up the Hierarchy until you find the same function name in this case it would be “OnFire();” and inherit everything that, that function holds

If i got something wrong i would appreciate it if you could correct me so i can see what i misunderstood

This is by no means comprehensive information on such a big topic, but a few key points are:

  • the ‘virtual’ specifier in a function declaration indicates that this function can be inherited/overriden in a derived class. It can still be accessed (called) from the child class even if it’s not virtual, as long as it’s not ‘private’ (it can be either ‘public’ or ‘protected’).

  • in a derived class you can override a virtual function of a parent class. All the ‘override’ specifier really does is throw a compile time error if no suitable function to override was found, like if you got the function signature wrong. The function would still be overridden even if you don’t specify ‘override’ if the parent function is virtual. Nevertheless it is good practice to specify override for functions you intend to override.

  • inside your overridden function you can still call the parent class implementation of the function, at any place in the function. UE specifically has a neat reflected way of doing this using the ‘Super’ keyword, e.g. Super::OnFire(); In vanilla c++ you would need to explicitly specify the base class.

  • What’s really the difference or point of virtual functions? What if OnFire wasn’t virtual? We could still define it just the same in both classes, and it would still work in the following case:

AWeaponBase* wbase = GetWeaponBase();

AWeaponRifle* wrifle = GetWeaponRifle();

The difference comes when you’re calling a function of a derived class from a pointer to the base class:

AWeaponBase* wbase = GetWeaponRifle();
wbase->OnFire(); //if OnFire is virtual, then AWeaponRifle::OnFire is called. Otherwise, AWeaponBase::OnFire is called.

Not quite :slight_smile:

Visibility is controlled via public, protected and private:

  • public means the function can be called by everyone (other classes and child classes),
  • protected means the function can be called only by child classes but not by other classes
  • private means the function is only callable by the class itself.

The virtual keyword does something similar to what you think override does.

It’s a bit differerent. Imagine this code:

class WeaponBase {
  public: virtual void OnFire() {}
class WeaponRifle : public WeaponBase {
  public: void OnFire() override {}

// someWeapon is actually an instance of WeaponRifle
void anotherFunction(WeaponBase *someWeapon) {

Which method will be called? The answer is WeaponRifle::OnFire() since someWeapon is an instance of WeaponRifle.
WeaponBase::OnFire() does not get called at all because it has been overridden.

If you wanted to call WeaponBase::OnFire(), you’d have to do it like this:

class WeaponRifle {
  public: void OnFire() override {
    WeaponBase::OnFire(); // call OnFire() of base class
    // more code

The cool thing about this is that you can write tons of code only dealing with WeaponBase. All that code doesn’t have to be changed when you invent additional weapons like, say, WeaponCrossbow because it doesn’t care, yet it still calls WeaponCrossbow::OnFire() if the WeaponBase pointer it is dealing with holds an instance of WeaponCrossbow

Finally, all that is due to the virtual keyword. override is made up by Epic (for readability, to highlight that a base class method is being overriden) but does precisely nothing :smiley:

It is not made up by Epic. It’s a formal keyword introduced in C++11 which generates a compile time error if no matching function signature is found in a base class.

Oops, thanks @RotemS. I picked up much of C++11 and C++14 but the override keyword at slipped by me :slight_smile:

Private functions can be called by any friend class in C++, even if the friend class isn’t a child of the one the function is declared in.
In UE4 I find myself unusually declaring and using friend classes quite often, never had to do it on other engines.