用于多态的引用和指针?

时间:2013-10-07 10:39:41

标签: c++ visual-c++ pointers polymorphism

我正在学习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类的任何方法,那么为什么要使用指针并为其分配对象?

3 个答案:

答案 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 virtualall 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
}