views:

501

answers:

3

In C++ when can a virtual function use static binding? If it is being accessed through a pointer, accessed directly, or never?

+2  A: 

Static binding can only be done when the object's type is totally unambiguous at compile time. I can only think of four places where an abstract object's type is unambiguous: in the constructor, in the destructor, when declared locally and within the same scope as a dynamic allocation. I don't know the standard that well so I couldn't say what it says about those four possibilities (I'd say the first two are statically bound, the third possible statically bound and the last not; although it probably says it's undefined or implementation dependent). Other than those points, the object being accessed through a base class pointer could be pointing to a derived class and the current translation unit has no way of knowing, so static binding is not possible. The function could be called with a pointer to the base class in one instance and a pointer to a derived class in another!

Skizz

Skizz
The optimizer may fuse different scopes via inlining. If the type is known in one of these scopes, it will be known in the fused scope.
MSalters
+3  A: 

If you want to call the base class version of a function, you can do that by explicitly naming the base class:

class Base
{
public:
  virtual ~Base() {}
  virtual void DoIt() { printf("In Base::DoIt()\n"); }
};

class Derived : public Base
{
public:
  virtual void DoIt() { printf("In Derived::DoIt()\n"); }
};

Base *basePtr = new Derived;
basePtr->DoIt();  // Calls Derived::DoIt() through virtual function call
basePtr->Base::DoIt();  // Explicitly calls Base::DoIt() using normal function call
delete basePtr;
Adam Rosenfield
Hah, I was in the middle of typing almost the exact same post! Upvoted yours.
Jim Buck
+6  A: 

When a virtual method is called through a pointer or reference, dynamic binding is used. Any other time, compile-time binding is used. Ex:

class C;

void Foo(C* a, C& b, C c) {
  a->foo();  // dynamic
  b.foo();  // dynamic
  c.foo();  // static (compile-time)
}