虚拟方法是否用于直到运行时才创建的方法? 我在理解C++中的虚拟方法的目的时遇到了一些困难。如果一个方法的对象不是在编译时创建的,那么它必须是虚拟的吗?例如,如果您必须在运行时选择一只农场动物,那么该动物的所有方法都需要是虚拟的,因为在用户选择一个之前,您不知道它是否将被创建。如果我错了,请纠正我。

虚拟方法是否用于直到运行时才创建的方法? 我在理解C++中的虚拟方法的目的时遇到了一些困难。如果一个方法的对象不是在编译时创建的,那么它必须是虚拟的吗?例如,如果您必须在运行时选择一只农场动物,那么该动物的所有方法都需要是虚拟的,因为在用户选择一个之前,您不知道它是否将被创建。如果我错了,请纠正我。,c++,methods,runtime,virtual,C++,Methods,Runtime,Virtual,阅读虚拟方法的用途。我还建议你们看看这本书。不,这是完全错误的。如果需要根据对象的类型选择方法,并且在编译时类型未知,则方法必须是虚拟的。如果您的代码如下所示: Animal *x; if(y==2) { x = new Animal(); x->DoSomething(); } 编译器在运行时知道x的类型是“Animal”。所以它知道该调用哪个版本的“DoSomething”。但看看这个代码: Animal *x; if(y==1) x=new Zebra(); els

阅读虚拟方法的用途。我还建议你们看看这本书。

不,这是完全错误的。如果需要根据对象的类型选择方法,并且在编译时类型未知,则方法必须是虚拟的。如果您的代码如下所示:

Animal *x;
if(y==2)
{
    x = new Animal();
    x->DoSomething();
}
编译器在运行时知道
x
的类型是“Animal”。所以它知道该调用哪个版本的“DoSomething”。但看看这个代码:

Animal *x;
if(y==1) x=new Zebra();
else if (y==2) x=GetSomeAnimal();
else x=new Giraffe();
x->DoSomething();
Animal * a = new Pig();
这里,
x
的类型在编译时是未知的。它可以是斑马、长颈鹿,也可以是
GetSomeAnimal
函数返回的任何类型的动物。无法知道调用
DoSomething
是否应该调用
Zebra::DoSomething
Giraffe::DoSomething
或其他完全不同的东西。所以
Animal::DoSomething
需要是虚拟的

<> P>并显示它与所创建的内容无关,请考虑如下:

void MyFunction(Animal &x)
{
    x.DoSomething();
}

void MyOtherFunction(int x)
{
   Giraffe g;
   Zebra z;
   if(x==2) MyFunction(g);
      else MyFunction(f);
}

这里很清楚,一只
长颈鹿和一只
斑马将被创造出来。但是如果
Animal::DoSomething
不是虚拟的,
MyFunction
将同时调用
Animal::DoSomething
而不是
Giraffe::DoSomething
在长颈鹿和
Zebra::DoSomething
在斑马上。(当然,如果你想这样,不要让方法虚拟化)

嗯,<代码>虚拟是C++中支持多态性的东西(特别是一个)。 当您希望相同类型的不同对象(
Animal
)根据上下文(无论
Animal
实际上是
Pig
还是
Cow
Chicken
还是…)表现不同时(
getProduceName()
返回“pork”或“beef”或“egg”或…)您将该行为/功能设置为虚拟的

通常一个好的OOD会有很好的接口/实现分离。C++中使用继承与<>代码>抽象<代码>类/方法实现。 因此,实际上,当您使
getProduceName()
polymorphic/
virtual
时,您实际上是在试图从不同的实现(
Pig
Cow
Chicken
或…)中提取接口(
Animal
),以保护您的客户端代码不受不同实现的影响。这样,如果您必须支持一个新的实现,您就不必更改客户机代码,只要它符合接口
Animal

所以要回答这个问题:如果一个方法的对象不是在编译时创建的,那么它是否必须是虚拟的

该方法是否为虚拟方法并不取决于对象的创建时间(编译/运行时)。这取决于您希望如何设计应用程序。使函数
虚拟化
有助于从不同的实现中提取接口。如果某些函数(
getOwnerName()
)在所有实现类(
{return ownerName;}
)中具有相同的实现,则不需要将其设为虚拟函数


PS:IMHO多态性是一个好的OOD的副产品,你不会设计你的类来实现“运行时多态性”,然后在你有一个好的OO设计时展示运行时多态性。

虚拟函数的一个更重要的目的是允许旧代码调用新代码

想想这个。函数将汽车对象作为参数。假设它执行测试驾驶()、加油()、计算能力()、getStoppingDistance()等操作。所有这些方法都取决于您输入的车型

但是每年都有新车问世。现在,在现实世界中,我们只需导入一个XML文件,其中包含构成所有汽车的属性。但是为了论证,假设我们必须静态地这样做:每次我们发现新车,我们都必须重建我们的整个程序。如果我们的计划很大,这将非常不方便。在某种程度上,我们调用的是相同的函数,但在某种程度上我们不是,因为对象的类型不同。我们为什么要重新编译


虚拟功能来拯救!当汽车制造商发布新车时,他们会同时发布一个声明新类型的头文件(该类型继承自具有虚拟函数的公共基类)和一个库(定义特定方法的对象文件)。因此,我们不再重新编译应用程序,而是重新链接到这个新库。因此,旧代码(我们的应用程序)可以调用新代码(汽车附带的新库)。

假设您有以下代码:

Animal *x;
if(y==1) x=new Zebra();
else if (y==2) x=GetSomeAnimal();
else x=new Giraffe();
x->DoSomething();
Animal * a = new Pig();
指针
a
的静态类型为
Animal
,动态类型为
Pig

现在我们打电话来

a->MakeASound();
如果
MakeASound
是虚拟的,则调用动态类型(
Pig
)的
MakeASound
方法


如果不是,则调用静态类型(
Animal
)的
MakeASound
,无论
Pig
是否覆盖
MakeASound
方法。

为什么标记为“C”?C++没有“方法”;它们被称为“成员函数”。成员函数没有“其对象”。一本好书可能是一个很好的开始学习C++的方法。你不能在运行时创建方法(在C++中,也就是说),并且你不能在运行时创建对象(除了包含对象模板或类似的东西的“对象”的一些外来定义”之外。代码>如果需要,请执行