哪些函数调用在编译时解析,哪些在运行时解析?我在某处读到并非所有函数调用都在编译时解析,我不知道哪个。
答案 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 foo
或new bar
构建。在运行时,我们知道obj
是从一个对象构造的,其返回的类型是bar*
,如果存在,则调用派生类的相应虚函数。另外调用基类虚函数。
obj->normalMethod();
这个方法可以在编译时解决,因为它是一个普通的成员函数。
答案 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(虚拟方法表)的表中记录所有虚拟功能详细信息,然后在运行时动态选择要使用的函数的正确版本。非虚函数在编译时解析,称为静态绑定。