关于c ++:用于多态的引用和指针?

reference and pointer used for polymorphism?

本问题已经有最佳答案,请猛点这里访问。

我学习C++,在运行时多态性中有问题吗?当创建类对象可以完成相同的工作时,为什么需要使用引用/指针?

"例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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(){}
}

现在在上面的例子中,我可以通过使用B类的对象来访问它的任何方法,并且使用范围解析来访问B类的一个类方法,那么为什么要使用指针并将对象分配给它呢?


假设你有3辆不同的车。你有不同的驱动机制。驾驶员不需要知道基本的发动机,只需要知道如何驾驶汽车的协议,即踩下踏板加速,踩下踏板刹车等。

现在从司机的角度来看,本田、福特或别克都不重要。从他看来,这只是一辆车。同样地,如果你把车停在车棚里,你就称它们为车棚。它拥有汽车,不为每辆车的制造而烦恼。所以

1
2
3
4
std::vector<Car*> v;
v.push_back(new Ferrari());
v.push_back(new Honda());
v.push_back(new Ford());

why do we need to use reference / pointer when same work can done by creating object of class?

如果没有指针或引用,则无法创建具有某些共性但在某些特定意义上不同的对象集合。在一些严格的OOP语言中,如Java、C等,通过使所有对象从一个称为EDCOX1〔0〕的基类派生而得到规避。C++是一种多范式语言,程序员可以自由地做出适合他/她的项目的决定。C++中的一种方法是通过基类指针。这个习语叫做运行时多态性。

1
2
for (const auto &this_car : v)
     this_car->drive();

在这里,无论实际的品牌是什么,只要基础类car是该车型的一部分,矢量v就能够容纳汽车。同样,每个品牌的drive也会有所不同,但调用它的函数不需要知道这一点。

编辑:

感谢Nijansen指出这篇文章并没有真正回答这个问题:为什么运行时多态性需要指针或引用(动态类型)?它只说它们必须用来实现它,但不能解释为什么我们不能使用普通(静态类型)变量。

C++是这样设计的,一个对象的类型可以在编译时完全可以知道,也可以不完全知道。在Circle c;中,我们知道cCircle型;而在Shape *p = make_shape();中,我们确实不知道p指的是什么对象;p自己的类型是Shape*型,但它指向对象的具体类型未知。我们所知道的是,它指向的是某个来自Shape的物体。请不要将自己与动态或自动内存分配混淆;对于自动变量(如Shape *p = &c;)也是如此。在这里,单独使用p,编译器不知道对象的具体类型,而p指向的具体类型。

如果我们把p写成静态(非指针、非引用)的Shape p = make_shape();Shape p = c;类型,那么切片中实际发生的情况,即p将是具体的Shape类型,而且由于它不是指针,因此它将复制(塑造)Circle对象的一部分c到它上面,这是最不可取的。

在不知道底层类型的情况下,如何调用正确的具体类型的函数?C++提供了虚拟函数来完成这项工作。这就是为什么运行时多态性总是用C++中的虚拟方法来解释的;而在像Java和C语言这样的语言中,所有的方法都是虚拟的,所有的对象类型都是引用/指针。在某种程度上,问题的答案是,语言的设计需要引用/指针变量来实现运行时多态性。


因此,您可以对每个对象进行一些通用的处理。例如,你有Chicken : Animal类,你有Cow : Animal类,它们有共同的功能doSlaughter()类,你有SlaughterHouseJob类。当您想处理slaughterHouseJob.doSlaughterAnimals()方法时,只需编写以下代码:

1
2
3
for(Animal animal:animals){
    animal.doSlaughter(); //It can be chicken or Cow or other animals. Simply one function for all jobs
}


为了给你一个一般的例子,

请原谅psedoucode。将在一段时间内添加CPP代码,现在有点生锈

超类

1
2
3
4
Class Animal
{

}

子类

1
2
3
4
5
6
7
8
9
Class Dog : public Animal
{

}

Class Cat : public Animal
{

}

另一个班,

1
2
3
4
5
6
7
class Vet
{
    void checkAnimal(recieve Animal)
    {

    }          
}

现在考虑一下这个用法,

1
2
vetObject.checkAnimal(dogObject);
vetObject.checkAnimal(catObject);

如果不是多态性,你的vet类应该是这样的,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Vet
{
    void checkAnimal(recieve Cat)
    {

    }          

    void checkAnimal(recieve Dog)
    {

    }          

     ....  and so on
}