我读过虚拟功能,但我无法清除这个概念。 在下面提到的例子中。我们创建一个基指针并首先分配基础对象,调用函数是基类,然后分配派生对象并调用其函数。既然我们已经提到过要分配哪些对象,那么编译时编译器不知道要调用哪个对象函数?我不明白为什么这个决定会延迟到运行时间。我在这里错过了什么。?
#include <iostream>
using std::cout;
using std::endl;
// Virtual function selection
class Base
{
public:
virtual void print() const
{
cout << "Inside Base" << endl;
}
};
class Derived : public Base
{
public:
// virtual as well
void print() const
{
cout << "Inside Derived" << endl;
}
};
int main()
{
Base b;
Derived f;
Base* pb = &b; // points at a Base object
pb->print(); // call Base::print()
pb = &f; // points at Derived object
pb->print(); // call Derived::print()
}
答案 0 :(得分:5)
在您的特定情况下,编译器可能会通过基类指针找出指针对象的类型。但虚拟调度机制是为在编译时没有此信息的情况而设计的。例如,
int n;
std::cin >> n;
Base b;
Derived d;
Base* pb = n == 42 ? &b : &d;
此处,根据用户输入进行选择。编译器无法知道pb
将指向的内容。
答案 1 :(得分:1)
既然我们已经提到过要分配哪些对象,编译器在编译期间不知道要调用哪个对象函数?我不明白为什么这个决定会延迟到运行时间。
在这个非常具体的设计案例中,你的编译器可以优化所有的多态性,是的。
我在这里遗漏了什么。?
想象中认识到现实生活中绝大多数代码都不是而不是这么简单。有无数的C ++程序,编译器没有足够的信息来执行这种优化。
答案 2 :(得分:0)
根据我的理解,编译器将在编译时查看引用类型并绑定在该类中定义和声明的函数。自衍生 - &gt;应该调用print()你必须在基类中使print函数成为虚函数,这样编译器就会将绑定延迟到运行时并使用派生类中定义的函数。
答案 3 :(得分:0)
由于它是虚拟的,它能够将函数动态绑定到正确的对象。这意味着调用该函数的指针将调用引用对象的函数。