Reputation: 75
class base
{
public:
static void func()
{
cout<<"in base class\n";
}
};
class derived: public base
{
public:
void func()
{
cout<<"In derived class\n";
}
};
main() {
derived d;
d.func();
}
If I make a function static in base class and create a function in derived class with the same name,why does that function get redefined even when it is static??
Upvotes: 1
Views: 2401
Reputation: 24249
You're experiencing "shadowing". The same thing is possible with member functions:
#include <iostream>
struct B {
void func() { std::cout << "in base\n"; }
};
struct D : public B {
void func() { std::cout << "in derived\n"; }
};
int main() {
D d;
d.func();
}
This - as others have suggested - is called "shadowing", one definition hides the other.
The important thing to remember here is that static function calling is resolved at compile time. So the following would have the behavior you had anticipated, but it is technically the wrong behavior because it prevents you from calling the top-most 'func' when using a base class pointer:
void callFunc(base* b) {
b->func();
}
int main() {
derived d;
callFunc(&b);
}
because at the call site, b->
points to base
and would call base::func
instead of derived::func
. At compile time, all the compiler knows is that 'b' is base
.
Most people expect and want the dynamic behavior:
#include <iostream>
struct Animal {
const char* say() { return "???"; }
};
struct Fox : public Animal {
const char* say() { return "A ring ding ding"; }
};
struct Cat : public Animal {
const char* say() { return "Meow"; }
};
void whatDoesItSay(const char* name, Animal* animal) {
std::cout << "The " << name << " says " << animal->say() << ".\n";
}
int main() {
Cat cat;
Fox fox;
whatDoesItSay("cat", &cat);
whatDoesItSay("fox", &fox);
}
This doesn't have the desired behavior:
Instead we need to use the keyword 'virtual' in the base class to indicate that we want fully polymorphic behavior, and we can use the new C++11 keyword 'override' to ensure we're doing it:
#include <iostream>
struct Animal {
virtual const char* say() { return "???"; }
};
struct Fox : public Animal {
const char* say() override { return "A ring ding ding"; }
};
struct Cat : public Animal {
const char* say() override { return "Meow"; }
};
void whatDoesItSay(const char* name, Animal* animal) {
std::cout << "The " << name << " says " << animal->say() << ".\n";
}
int main() {
Cat cat;
Fox fox;
whatDoesItSay("cat", &cat);
whatDoesItSay("fox", &fox);
}
Upvotes: 1
Reputation: 45654
It does not get redefined, or you would violate the one-definition-rule.
What you see is "scope":
If a name is defined in an inner scope, it shadows (hides) all definitions of the same name in an outer scope.
You can still refer to the function in the outer scope (base class) with an explicit qualification:
base::func
In order to add those from the outer scope to the overload set, use a using
-declaration:
using base::func;
If you do so, base::func
will be called when using derived::func()
and derived::func
will be called when using derivedobject.func()
.
Upvotes: 1
Reputation: 4291
It doesn't get redefined, if it did you would have a compilation error due to the one definition rule. You have 2 functions here, one a member, and one static. d.func()
is the member function ( as the .
suggests ). The other function is base::func()
, which is the static function ( as ::
suggests ).
Upvotes: 2