我正在学习c ++。我在常设运行时多态中遇到问题? 为什么我们需要通过创建类的对象来完成相同的工作时使用引用/指针?
`例如:
class A{
private:
int p;
public:
A(){} //ctor
void Print(){}
void display(){}
void showrecord(){}
}
class B:public A
{
Private:
int q;
public:
B(){} //ctor
void Print(){}
void displayrecord(){}
}
现在在上面的情况下,我可以通过使用其对象和A类方法b使用范围解析来访问B类的任何方法,那么为什么要使用指针并为其分配对象?
答案 0 :(得分:1)
让我们说你有3种不同的车。你有不同的驱动机制。驾驶员不需要了解底层发动机,而只需要了解如何驾驶汽车的协议,即按下踏板加速,按下踏板进行制动等。
现在从司机的角度来看,无论是本田,福特还是别克都没关系。从他的观点来看,它只是一辆汽车。同样地,如果你已经脱落,停放汽车的地方,你称他们为汽车棚。它装有汽车,并不关心每个人是什么。所以
std::vector<Car*> v;
v.push_back(new Ferrari());
v.push_back(new Honda());
v.push_back(new Ford());
为什么我们需要通过创建类的对象来完成相同的工作时使用引用/指针?
如果没有指针或引用,则无法创建具有某些共性但在某种特定意义上不同的对象集合。通过使所有对象派生自名为Object
的基类,可以在诸如Java,C#等一些严格的OOP语言中规避这种情况。 C ++是一种多范式语言,程序员可以自由地做出适合他/她项目的决策。在C ++中实现它的方法是通过基类的指针。这个成语叫做运行时多态。
for (const auto &this_car : v)
this_car->drive();
这里无论实际的make是什么,只要基类v
是该类型的一部分,向量car
就能够保存汽车。同样地,drive
对于每个品牌都会有所不同,但对于调用它的函数不需要知道。
修改强>
感谢nijansen指出这篇文章实际上没有回答这个问题:为什么运行时多态性需要指针或引用(动态类型)?它只是说他们已经习惯了它,但没有解释为什么我们不能使用普通(静态类型)变量。
C ++的设计方式是,在编译时只需要手中的类型就可以完全知道对象的类型。在Circle c;
我们知道c
的类型为Circle
;而在Shape *p = make_shape();
中我们真的不知道对象p
指向的是什么; p
自己的类型是Shape*
,但它的指向对象的具体类型是未知的。我们所知道的是它指向了一个源自Shape
的对象。请不要将自己与动态或自动内存分配混淆;对于自动变量,这也是相同的例如。 Shape *p = &c;
。这里p
也是孤立的,编译器不知道对象是什么具体类型,p
指向的是什么。
我们是否将p
写为静态(非指针,非参考)类型Shape p = make_shape();
或Shape p = c;
slicing中真正发生的事情,即p
将是具体类型Shape
,因为它不是指针,它会将Circle
对象c
的一部分复制(形状)到它,这是不可取的。
在不知道基础类型的情况下,我们如何调用正确的具体类型的函数? C ++提供了虚拟功能来完成这项工作。这就是为什么运行时多态性总是用C ++中的虚方法解释的原因;而在Java和C#all methods are virtual和all object types are references/pointers等语言中。在某种程度上,您的问题的答案是,语言的设计使得人们需要运行时多态性的引用/指针变量。
答案 1 :(得分:0)
给你一个一般的例子,
请原谅pseduocode。将在一段时间内添加一个Cpp代码,现在有点生锈
超级
Class Animal
{
}
子类
Class Dog : public Animal
{
}
Class Cat : public Animal
{
}
另一个班,
class Vet
{
void checkAnimal(recieve Animal)
{
}
}
现在考虑一下这种用法,
vetObject.checkAnimal(dogObject);
vetObject.checkAnimal(catObject);
如果不是为了多态,你的Vet Class会是这样的,
class Vet
{
void checkAnimal(recieve Cat)
{
}
void checkAnimal(recieve Dog)
{
}
.... and so on
}
答案 2 :(得分:0)
因此,您可以对每个对象执行一些通用处理。例如,您拥有Chicken : Animal
类,并且您拥有Cow : Animal
类,并且它们具有公共函数doSlaughter()
,并且您具有SlaughterHouseJob
类。当您想要处理slaughterHouseJob.doSlaughterAnimals()
方法时,您只需编写以下代码:
for(Animal animal:animals){
animal.doSlaughter(); //It can be chicken or Cow or other animals. Simply one function for all jobs
}