在面向对象编程的编译时哪些函数调用没有解决?

时间:2011-02-18 08:21:30

标签: c++ oop

哪些函数调用在编译时解析,哪些在运行时解析?我在某处读到并非所有函数调用都在编译时解析,我不知道哪个。

5 个答案:

答案 0 :(得分:4)

虚拟函数调用机制在运行时解析。因为,在 C ++ 中,指向派生类的指针与指向其基类的指针类型兼容。因此,要调用虚函数,必须知道基类指针所指向的构造对象(或实际的卧底对象)的实际类型,这只能在运行时解析。

struct foo
{
     virtual void virtualMethod()
     {
          cout<< " \n virtualMethod of foo \n";
     }

     void normalMethod()
     {
          cout<< " \n normalMethod of foo \n";
     }
     virtual ~foo() {}
};

struct bar: public foo
{
     void virtualMethod()
     {
         cout<< " \n virtualMethod of bar \n";
     }
     void normalMethod()
     {
          cout<< " \n normalMethod of bar \n";
     }
     ~bar() {}
};

foo* obj = new bar ;
obj->virtualMethod() ;

现在,因为需要调用哪个virtualMethod()取决于运行时类型(或实际不足的对象)obj指向,因为obj可以指向一个对象由new foonew bar构建。在运行时,我们知道obj是从一个对象构造的,其返回的类型是bar*,如果存在,则调用派生类的相应虚函数。另外调用基类虚函数。

obj->normalMethod();

这个方法可以在编译时解决,因为它是一个普通的成员函数。

结果:ideOne results link

答案 1 :(得分:2)

如果您的意思是使用多态性调用

编译时间:运算符和函数重载。 并在运行时:虚拟功能。

答案 2 :(得分:1)

它们可能意味着虚函数,它必须通过某种机制(通常是vtable)来根据当前实例调用正确的方法。

例如:

class A
{
    public:
        virtual ~A(){}
        virtual void DoStuff() { cout << "A"; }   
};

class B : public A
{
    public:
        virtual void DoStuff() { cout << "B"; }
};

void Magic(A &x)
{
    x.DoStuff();
}

现在,在Magic()方法中,编译器无法确定将哪个实例传递给该方法。它可以是A的实例,也可以是B的实例。必须被调用的方法在每种情况下都是不同的。因此调用没有完全解决,而是通过一些中间机制,选择适当的方法。

答案 3 :(得分:1)

虚拟功能将在运行时解析。 术语动态绑定或后期绑定用于描述这些函数。

这两个术语都暗示,解析在运行时发生,具体取决于对象的实例化方式。

请注意,虚函数不是后期绑定的唯一示例。函数指针可以达到同样的效果。

int Add(int nX, int nY)
{
    return nX + nY;
}
int Subtract(int nX, int nY)
{
    return nX - nY;
}

int main()
{
    // Create a function pointer and make it point to the Add function
    int (*pFcn)(int, int) = Add;
    cout << pFcn(5, 3) << endl; // add 5 + 3
    pFcn = Subtract;
    cout<< pFcn(5,3)<<endl // pefrom 5-3
    return 0;
}

答案 4 :(得分:0)

使用运行时绑定功能时,在编译时不会解析函数调用。这通常是使用虚函数的多态性。在这种情况下,运行时会在名为VMT(虚拟方法表)的表中记录所有虚拟功能详细信息,然后在运行时动态选择要使用的函数的正确版本。非虚函数在编译时解析,称为静态绑定。