C+中的虚函数+; 我的C++程序: #include<iostream.h> class A { public: virtual void func() { cout<<"In A"<<endl; } }; class B:public A { public: void func() { cout<<"In B"<<endl; } }; class C:public B { public: void func() { cout<<"In C"<<endl; } }; int main() { B *ptr=new C; ptr->func(); } #包括 甲级 { 公众: 虚空函数() { cout

C+中的虚函数+; 我的C++程序: #include<iostream.h> class A { public: virtual void func() { cout<<"In A"<<endl; } }; class B:public A { public: void func() { cout<<"In B"<<endl; } }; class C:public B { public: void func() { cout<<"In C"<<endl; } }; int main() { B *ptr=new C; ptr->func(); } #包括 甲级 { 公众: 虚空函数() { cout,c++,virtual-functions,C++,Virtual Functions,了解您应该阅读的基础知识 虚拟函数允许派生类替换基类提供的实现。编译器确保每当所讨论的对象实际属于派生类时,始终调用替换,即使该对象是由基类指针而不是派生指针访问的。这允许基类中的算法在派生类中被替换,即使用户不知道派生类 声明后,虚函数在所有派生类中都是虚函数(无论是否显式指定)。因此func()在A、B和C类中是虚函数。该语句应调用B::func() 由于指针指向类C的对象,它将调用类C中的函数 虚拟函数导致,这意味着要调用的函数将根据指针指向的对象而不是编译时声明的指针类型来决定。这是多态

了解您应该阅读的基础知识

虚拟函数允许派生类替换基类提供的实现。编译器确保每当所讨论的对象实际属于派生类时,始终调用替换,即使该对象是由基类指针而不是派生指针访问的。这允许基类中的算法在派生类中被替换,即使用户不知道派生类


声明后,虚函数在所有派生类中都是虚函数(无论是否显式指定)。因此func()在A、B和C类中是虚函数。

该语句应调用B::func()

由于指针指向类
C
的对象,它将调用类
C
中的函数


虚拟函数导致,这意味着要调用的函数将根据指针指向的对象而不是编译时声明的指针类型来决定。

这是多态性的本质。主函数不需要知道
ptr
实际上是指向类
C
的对象,它只需要知道可用的接口至少是类
B
中定义的接口(这就是为什么您将其声明为
B*ptr
,如果您需要特定于
C
的函数,则必须执行
C*ptr

当你说函数在B中是虚拟的,这意味着它可能被一个子类重载,编译器生成代码来寻找这个替代实现。在这种情况下,它在
C
(每个编译器的实际细节可能不同,但大多数编译器让对象携带一个表,即所谓的虚拟表,将
func()
映射到特定的实现),并调用该表


如果没有虚拟关键字,这会告诉编译器不可能有替代实现,并将其直接硬链接到B实现。

如果您愿意:

B *obj = new B;
然后它会调用B::func() 要获得预期的功能性,应删除C中func的新实现。
如果你使用一个虚拟函数,你实际上会说我不知道我里面有什么类型的对象,只要它来自同一个对象家族(在这里,a是“家族”的“父亲”)。你所知道的只是“家族”的每个成员都必须为特定的部分做不同的工作。例如:

class Father
{
public:
  virtual void func() { cout << "I do stuff"; }
};
class Child : public Father
{
public:
  virtual void func() { cout << "I need to do something completely different"; }
};

int main()
{
  Father *f = new Father;
  f->func(); // output: I do stuff
  delete f;
  f = new Child;
  f->func(); // output: I need to do something completely different
  delete f;
}
班长
{
公众:
virtualvoid func(){cout func();//输出:我需要做一些完全不同的事情
删除f;
}

但是,我在类B中重新定义了func(),这一事实难道没有带走函数的虚拟本质吗?请阅读常见问题解答:)如果在基类中使方法虚拟,则无需在任何派生类中放置
virtual
关键字-无论如何它都将是虚拟的。如果使用不同的参数重载函数,则它将以非虚拟方式工作。