Override and Overload in C++

Override and overload in C++

Overloading generally means that you have two or more functions in the same scope having the same name. The function that better matches the arguments when a call is made wins and is called. Important to note, as opposed to calling a virtual function, is that the function that's called is selected at compile time. It all depends on the static type of the argument. If you have an overload for B and one for D, and the argument is a reference to B, but it really points to a D object, then the overload for B is chosen in C++. That's called static dispatch as opposed to dynamic dispatch. You overload if you want to do the same as another function having the same name, but you want to do that for another argument type. Example:

void print(Foo const& f) {
// print a foo
}

void print(Bar const& bar) {
// print a bar
}

they both print their argument, so they are overloaded. But the first prints a foo, and the second prints a bar. If you have two functions that do different things, it's considered bad style when they have the same name, because that can lead to confusion about what will happen actually when calling the functions. Another usecase for overloading is when you have additional parameters for functions, but they just forward control to other functions:

void print(Foo & f, PrintAttributes b) { 
/* ... */
}

void print(Foo & f, std::string const& header, bool printBold) {
print(f, PrintAttributes(header, printBold));
}

That can be convenient for the caller, if the options that the overloads take are often used.

Overriding is something completely different. It doesn't compete with overloading. It means that if you have a virtual function in a base class, you can write a function with the same signature in the derived class. The function in the derived class overrides the function of the base. Sample:

struct base {
virtual void print() { cout << "base!"; }
}

struct derived: base {
virtual void print() { cout << "derived!"; }
}

Now, if you have an object and call the print member function, the print function of the derived is always called, because it overrides the one of the base. If the function print wasn't virtual, then the function in the derived wouldn't override the base function, but would merely hide it. Overriding can be useful if you have a function that accepts a base class, and every one that's derived from it:

void doit(base &b) {
// and sometimes, we want to print it
b.print();
}

Now, even though at compile time the compiler only knows that b is at least base, print of the derived class will be called. That's the point of virtual functions. Without them, the print function of the base would be called, and the one in the derived class wouldn't override it.

Difference between overriding and overloading of a function in C++

overloading means functions with same name having different parameters , it does not really depend whether you are using procedural language or object oriented language you can do overloading. well as far as over riding is concerned it means we are explicitly defining a function that exist in base class in derived class . obviously you need object oriented language to perform over riding as it is done between base and derived classes.

C++ - Overloading vs Overriding in Inheritance

In C++, any method in a derived class only overrides the method in the base class if their declarations match (I say "match" but I don't know the formal term for that). That is, all arguments must have the same type, and const qualification of this must be the same. If anything there mismatches, the method in the derived class hides all methods with the same name, instead of overriding. This is what the "ERROR" in your picture tries to tell you. So // overrides in a comment in that picture is incorrect and misleading.

Yes, many C++ teachers actually don't understand these somewhat obscure details.

BTW additionally, if you want to override, the method in your base class should be virtual; otherwise, polymorphism won't work. If it was not virtual, we also say that the derived-class method hides the base-class method. Here, however, the part about hiding has almost no meaning; what this term really wants to express is that you're not overriding.

In addition, overloading is, as you noticed, presence of several methods with the same name but different signatures. They should all be present in the derived class to be useful - if the derived class has only one method fa1, and the other fa1 are in the base, they will be hidden. However, there is syntax sugar which "copies" all fa1 from base to derived, disabling all that hiding semantics:

class A
{
public:
void fa1();
void fa1(int);
};

class B: public A
{
public:
using A::fa1;
void fa1(int, int);
};

...
B b;
b.fa1(); // calls A::fa1()
b.fa1(4); // calls A::fa1(int)
b.fa1(4, 8); // calls B::fa1(int, int)

The part about hiding is rarely, if ever, useful. When overriding, you should tell this to your compiler - use the override keyword for that. The compiler will then check that your code works as you intended.

class A
{
public:
virtual void fa1(int) {}
void fa2(int) {}
};

class B: public A
{
public:
void fa1(int) override {} // OK
void fa1() override {} // ERROR: doesn't really override - different signature
void fa2(int) override {} // ERROR: doesn't really override - not virtual in base
};

Differentiate between function overloading and function overriding

You are putting in place an overloading when you change the original types for the arguments in the signature of a method.

You are putting in place an overriding when you change the original Implementation of a method in a derived class.

Simultaneous overriding and overloading in C++

This is name hiding. Derived::show hides the methods with the same name in Base. You can introduce them by using.

class Derived:public Base{
public:
using Base::show;
void show(int x){
cout<<"Method show in derived class."<<endl;
}
};

C++: override or overload?

This is neither overriding nor overloading. Since the parameter's type is different, MyDerived::doSome is just hiding MyBase::doSome.

1.1. Since DerivedContext derives from BaseContext, it might seems that I am overriding doSome.

No. Here're the preconditions of overriding listed in the standard. $10.3/2 Virtual functions
[class.virtual]:

(emphasis mine)

If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list ([dcl.fct]), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides110 Base::vf.

110) A function with the same name but a different parameter list (Clause [over]) as a virtual function is not necessarily virtual and does not override.

In fact with override specifier you'll get a compile error for this case. e.g.

error: 'doSome' marked 'override' but does not override any member functions

1.2. But it might also be an overloading...

You can't overload functions across scopes according to the rule of unqualified name lookup (unless using using-declaration to introduce names into the same scope).


  1. Thus, if I type (MyBase* my = new MyDerived())->doSome(new DerivedContext()), what should I get?

MyBase::doSome() will be invoked since you call it on a MyBase*. This is not overriding, so no dynamic dispatching happens here.

LIVE

Note the argument DerivedContext* will be implicitly converted to BaseContext* and then passed to the function. BTW (MyBase* my = new MyDerived())->... is not valid syntax.

Is the method overridden or overloaded?

B::fun neither overloads nor overrides A::fun. It hides it. It's not an override because you can still get the A::fun behavior on a B by treating it as an A

B x;
A &y = x;
y.fun(); // outputs Parent

When you try to access the fun method through the A interface, you get the Parent behavior. Were A::fun declared virtual, then B::fun would override it and the fun method accessed through the A interface would output Child.

The difference between overloading and hiding is not clear here because the argument lists are the same, but consider the hierarchy

struct A {
void foo(int i) { std::cout << i << "\n"; }
};
struct B : A {
void foo(std::string const &s) { std::cout << std::quoted(s) << "\n"; }
};

If B::foo just overloaded A::foo then this would work

B x;
x.foo(5);

But it does not. Note that x still has the foo(int) method.

A &y = x;
y.foo(5); // works

You just can't get to it through the B interface. This is because overload resolution is only done among the set of members declared in the same class. If a class doesn't declare a member of the name, then it goes to the base classes, but if the class does declare the name and none of them match, the resolution just fails right there. (I.e. removing B::foo would make x.foo(5) work.)

You can request overloading instead of hiding from the language with a using directive, but again overriding is impossible unless A::fun is virtual (and B::fun would need to have the same argument list as A::fun).

struct B : A {
using A::foo;
void foo(std::string const &s) { std::cout << std::quoted(s) << "\n"; }
};

(P.S. Regarding the comments, the technical term in C++ is indeed hiding. Shadowing may be the word used for this behavior in other languages, but the C++ standard uses "hiding".)

Overriding a Base's Overloaded Function in C++

In class bar, add

using foo::a;

This is a common 'gotcha' in C++. Once a name match is found in the a class scope, it doesn't look further up the inheritance tree for overloads. By specifying the 'using' declaration, you bring all of the overloads of 'a' from 'foo' into the scope of 'bar'. Then overloading works properly.

Keep in mind that if there is existing code using the 'foo' class, its meaning could be changed by the additional overloads. Or the additional overloads could introduce ambiguity and and the code will fail to compile. This is pointed out in James Hopkin's answer.

overloading vs overriding

In this case neither. The derived-class method hides the base-class method.



Related Topics



Leave a reply



Submit