Reputation: 115
class BaseClass {
public:
virtual void method1(){
method2();
};
virtual void method2(){
std::cout << "Base Method" << std::endl;
};
}
class DerivedClass : public BaseClass {
virtual void method2(){
std::cout << "Derived Method" << std::endl;
};
}
int main() {
DerivedClass derived;
derived.method1();
}
In the above example I get "Derived Method" as the output - Why does this happen?
I understand that DerivedClass
inherits from BaseClass
, and therefore derived
can call method1
, but I don't understand why method2
from DerivedClass
hides method2
from BassClass
when it is being called from BaseClass
.
Apologies for any bad code/mistakes - still new to C++.
Upvotes: 4
Views: 176
Reputation: 1074
Try removing virtual
keyword from method2()
of BaseClass
.
This will give you output as "Base Method". This is static binding and as method1
of BaseClass
is called, so is method2
of BaseClass
called.
In contrast, virtual member functions are resolved dynamically (at run-time). That is, the member function is selected dynamically (at run-time) based on the type of the object. So an object of DerivedClass
will always call method2
of derived class only and output will be "Derived class".
Upvotes: 0
Reputation: 2524
derived.method1()
statically binds the function call BaseClass::method1()
, however this function calls the virtual function method2()
. This causes dynamic binding to DerivedClass::method2()
instead of calling BaseClass::method2()
.
If you want to statically bind BaseClass::method2()
in BaseClass::method1()
, you must do this:
class BaseClass {
public:
virtual void method1(){
BaseClass::method2(); //explicit class scope prevents dynamic binding
}
virtual void method2(){
std::cout << "Base Method" << std::endl;
}
};
Upvotes: 2
Reputation: 8926
Because you declared it virtual. If you don't want that behavior, remove the virtual declaration. Virtualization is vital to the whole notion of inheritance and object oriented programming. See "The C++ Programming Language (Special Edition)" chapter 12 for an in depth discussion.
Upvotes: 0
Reputation: 101456
Because method2
is virtual
.
When you declare a function as virtual
, what you're really doing is making it so that when the method is called via a pointer or reference (in other words, in a normal way) the function that is actually called is the most-derived overload.
This is a Good Thing, and usually exactly what you want. Note that it doesn't matter from what context you make the call. Your'e calling method2
from the context of the base class, which has an implementation of method2
available. Presumably, you're assuming that since your calling from the base class that the base class' implementation is the one that will be called.
That's not how virtual
s work -- and that's also a Good Thing.
You can, if you wish, call the version in the base class by being explicit about it:
class BaseClass {
public:
virtual void method1(){
BaseCLass::method2();
};
But this is usually not desirable, and in my book, a code smell.
Upvotes: 3