Scope Resolution Confusion When Overriding Virtual Function

Hello Unreal-ites,

In C++, is the usage of a scope resolution operator incorrect syntax when overriding a virtual function?
Below are two class header examples. Is Scope Resolution considered Syntactically Incorrect when overriding a function found within a parent class?

Class A
{
virtual void SomeFunc();
}

First example of Class B using scope resolution
Class B : A
{
void A::SomeFunc() override; <---- IS THAT INCORRECT SYNTAX??
}

Second example of Class B NOT using scope resolution (this works, but why is it incorrect to use scope resolution here?)
Class B : A
{
void SomeFunc() override; <— IS THAT CORRECT SYNTAX? If so, why? Why is it scope resolution does not work here / is not supposed to be here?
}

-Erol

Hope those links will helpful:
https://en.cppreference.com/book/intro/inheritance
https://en.cppreference.com/w/cpp/language/override

You can use the scope resolution operator if you specifically wants to call a parent function (or just use the “Super” shorthand in UE4).

Functions can be overridden when they are made virtual and the compiler will know that you want to override if you try to declare a function using a parent signature. Using the override keyword makes it explicit so you will get warned if there isn’t any parent function to be overridden.

I have modified my original post to make things more clear…

Thank you for responding @mdeni , I’m not sure how I can relate my question to the inheritance link. It does not illustrate scope resolution which makes me believe these examples are not to be referenced as header files, but rather implementation files as there are no include statements. I should have been more up front: My initial post is modified to explain that these are header file examples…

It appears if I declare Class A and declare a virtual function in class A, when declaring Class B to inherit from class A, and I want to declare an override to the virtual function in A, an error is thrown if I try to use Scope Resolution as shown in the example. In C++ (and/or in Unreal) should I receive an error if I try to use a scope resolution operator when overriding a virtual function?

Hey @GarnerP57 , In my example (not the real issue I have as I wanted to post the least number of chars as possible to illustrate the problem/question), I can assure you that Class A has a virtual function, and Class B is inheriting from Class A, and Class B is overriding the virtual function in A. The question is, in C++, is scope resolution syntactically incorrect when overriding a virtual function?

If both of you want, I can show you the real example with the errors that are thrown if you want.

Public inheritance represents IS-A relationship, so derived class (even empty) inherit all public members and functions from base class.
BTW inheritance is probably most overused feature in cpp.



struct A
{
  void plain_function();
  virtual void virtual_function();
}

struct B : public A
{
};

struct C : public A
{
  void virtual_function() override
  {
    A::virtual_function(); // call A::virtual_function()
    // do stuff...
  }
};

void func()
{
  B b;
  b.plain_function();  // calls A::plain_function()
  b.virtual_function(); // calls A::virtual_function()
  C c;
  c.plain_function(); // calls A::plain_function()
  c.virtual_function(); calls C::virtual_function()
}


Hi @Emaer ,

I understand inheritance. My confusion lies with using scope resolution inside a header that is overriding a function that it inherited from another class. I do believe the answer to my question is: scope resolution in a function override declaration is, syntactically, an error. Correct?.

On another note: Why do you feel inheritance is the most over-used feature in C++? That’s like saying (in my opinion) Relational Design is the most over-used feature in Databases.
How is one able to achieve polymorphism without inheritance?
How is one able to get code reuse through objects of similar characteristics?

-Erol

Yes. [C++] gcc HEAD 10.0.0 20191224 (experimental) - Wandbox

Composition is much better. More decoupled, more testable, easier to maintain and replace.
Other options for code reuse is using templates or type erasure technique.

Hi @Emaer ,

Thank you for the example and suggestions of other design paradigms. I would say it’s fair to argue that it depends on the nature of the problem to be solved, no?

Composition seems to be the choice for a lot of developers because, like you said, inheritance can be tricky with testing and other issues like the infamous diamond result. But all of that comes with poor design / implementation / engineering / unit & integration testing, no?

I believe inheritance, at least to me, makes more sense when designing a particular portion of a game. Take different enemies or different items… An Orc is an enemy, and so is a Super Orc, and so is a Troll. A Health Potion is an Item, and so is Speed Buff, and so is a Debuff Potion… I’d rather rely on polymorphism and let the inheriting classes override as necessary: EnemyBase.Attack(). or ItemBase.UseItem().

Composition does seem like a cool way to implement some behaviors/attributes with references to classes that give them behaviors and/or attributes. Powerups / New Abilities could be very useful here. I guess that’s why many developers also choose to implement different design paradigms in the same project.

Inheritance testing issues… Do interfaces not solve that problem, at least more than marginally?

Would like to hear your thoughts.

-Erol

You can easily use both inheritance and composition. The problem with inheritance is that you easily end up with a large tree structure that has to be managed and before you know it you have to move redundant functions around that could have been encapsulated in a component instead.

Every time you add a function to a base class it has to be valid for every possible derived class or you will have some redundant and confusing functions in the derived class.

Inheritance just isn’t very flexible compared to composition but that doesn’t mean you should not use inheritance when you are absolutely sure you will need those functions everywhere like with a character or item but those are the prime examples.

Sure, there is no “bad things”. It’s always bad use of things :slight_smile:
There are a few good rules that make OOP really good to use (like Non-Leaf Class Always Abstract, Non-Virtual Interface, SOLID, etc.). Unfortunately they are rarely used.
Look at AActor class. They have over 250 public methods(without private/protected and derived from UObject). If my actor define 20 methods, it is nearly 300 methods exposed to anyone! There is countless cases of who, when and in what order call them.

In theory, yes. But it always ends with bunch of downcasting for check what is the real type of enemy/item and how it affects another downcasted real type.
What’s the differences between Orc and SuperOrc? Excluding behaviours, they are technically the same :slight_smile:

At least using interfaces can help, but its still limited approach - multiple inheritance comes to game.