所以我在C ++中遇到了一个叫做虚函数的东西,简而言之就是我所理解的用于在派生/子类中启用函数重载。
因此我们有以下课程:
class MyBase{
public:
virtual void saySomething() { /* some code */ }
};
然后当我们创建一个继承MyBase的新类时:
class MySubClass : public MyBase{
public:
void saySomething() { /* different code than in MyBase function */ }
};
MySubClass中的函数将执行自己的saySomething()函数。
要理解它,是否与Java相同,只需在派生类中编写相同的函数名称即可实现相同的功能,这将自动覆盖/重载它?
在C ++中实现的目标是什么,你需要额外的步骤,即将基类中的函数声明为虚拟?
提前谢谢! :)
答案 0 :(得分:6)
是的,你是对的。在Java中,所有函数都是隐式虚拟的。在C ++中,您可以选择:为了使函数成为虚拟函数,您需要在基类中将其标记为这样。 (有些人还在派生类中重复虚拟关键字,但这是多余的。)
答案 1 :(得分:5)
在c ++中,虚拟功能需要付出代价。为了能够提供多态,重载等,您需要将方法声明为虚拟。
由于C ++关注程序的布局,virtual
关键字带来了可能不需要的开销。 Java被编译为字节码并在虚拟机中执行。 C ++和本机汇编代码直接在CPU上执行。这使您(开发人员)有可能完全理解和控制代码在汇编程序级别(在优化等之后)的外观和执行方式。
在C ++类中声明任何virtual
会为每个类创建一个vtable
条目,完成整个重载操作。
还有编译时多态与模板,可以减轻vtable
和解决方案开销,它有自己的一系列问题和可能性。
答案 2 :(得分:1)
让我们这样说吧。
MyBase *ptr; // Pointer to MyBase
ptr = new MySubClass;
ptr->saySomething();
如果saySomething
中virtual
不 MyBase
,则基类版本始终将被调用。如果它是virtual
,则将使用任何派生版本(如果可用)。
答案 3 :(得分:1)
虚函数只是一个函数重载?
没有。 "重载"意味着提供具有相同名称但不同参数类型的多个函数,并在编译时选择适当的函数。 "重写"表示在类层次结构中提供多个函数,并在运行时选择适当的函数。在C ++中,只能覆盖虚函数。
要理解它,并不像在Java中那样通过在派生类中简单地写入相同的函数名来实现相同的功能,它会自动覆盖/重载它吗?
是的,假设您的意思是"覆盖"。在Java中,默认情况下方法是可覆盖的。这符合Java(原创)的理念,即我们应该使用90年代风格的面向对象的范例。
用C ++实现的目的是你需要额外的步骤,即将基类中的函数声明为虚拟?
使函数可覆盖具有运行时成本,因此C ++仅在您特别请求时才执行此操作。这符合C ++的理念,即您应该为您的应用选择最合适的范例,而不是为您不需要的语言设施付费。