编译器如何解决函数?

编译器如何解决函数?

问题描述:

如何确定以下调用是在编译时还是在运行时绑定?

How it is determined whether the below call is bound at compile time or at runtime?

object.member_fn;//object is either base class or derived class object
p->member_fn;//p is either base class or derived class pointer

已编辑:

#include <iostream>
using namespace std;
class Base
{
       public:
          Base(){ cout<<"Constructor: Base"<<endl;}
          ~Base(){ cout<<"Destructor : Base"<<endl;}
};
class Derived: public Base
{
     //Doing a lot of jobs by extending the functionality
       public:
           Derived(){ cout<<"Constructor: Derived"<<endl;}
           ~Derived(){ cout<<"Destructor : Derived"<<endl;}
 };
void foo()
{
    Base & Var = Derived();
    Base*pVar = new Derived;
    delete pVar;
}
void main()
{
    foo();
        std::cin.get();
}


out put:
Constructor: Base
Constructor: Derived
Constructor: Base
Constructor: Derived
Destructor : Base // the Derived is not called,
                  // the PVal is of type Base* and the fn is not virtual 
                  //so compile time binding
Destructor : Derived
Destructor : Base


virtual,这两个调用都将在编译时解决。如果方法是virtual,那么在你的问题( obj.method())中的第一个调用将在编译时解析为一个对象,但是在运行时为一个引用。第二个调用( objp-> method())将在运行时解析。您也可以在编译时强制调用方法的非派生版本。

If the method is not virtual, both calls will be resolved at compile time. If the method is virtual then the first call in your question (obj.method()) will be resolved at compile time for an object, but at runtime for a reference. The second call (objp->method()) will be resolved at runtime. You can also force at compile time to call the non-derived version of a method.

struct base {
   void f();
   virtual void v();
};
struct derived : public base {
   void f();
   void v(); // intentionally left virtual out, it does not really matter
};
int main() {
   derived d;
   base & b = d;
   base * bp = &d;

   // compile time:
   d.f();   // derived::f
   d.v();   // derived::v
   b.f();   // base::f   -- non-virtual
   bp->f(); // base::f   -- non-virtual

   // runtime:
   b.v();   // derived::v
   bp->v(); // derived::v

   // compile time (user forced):
   b.base::v();   // base::v
   bp->base::v(); // base::v
}