neharika
neharika

Reputation: 75

redefinition of static function in case of inheritance

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

Answers (3)

kfsone
kfsone

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();
}

http://ideone.com/kjt2Oa

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);
}

http://ideone.com/9wIzq7

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);
}

http://ideone.com/uOtYMv

Upvotes: 1

Deduplicator
Deduplicator

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

Ylisar
Ylisar

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

Related Questions