多态性:在没有指针的情况下调用覆盖的函数 [英] polymorphism: calling overrided functions without pointers

查看:77
本文介绍了多态性:在没有指针的情况下调用覆盖的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用C ++做一些实验. 我对某些多态行为很不满意. 在其他语言(例如c#)中,当我将基于派生类的对象分配给BaseType对象时:此对象开始使用派生类代码.或者,如果我有一个BaseType对象的列表,并在其中放入了基于派生类的对象:每个元素都根据特定的Type工作. 在C ++中... 我仅使用指针就在C ++中获得了这种特性. 还有其他方法吗?我错过了什么吗? 这是我的代码示例:

I am doing some experimentation with C++. I've been imporessioned by some behaviours with polymorphism. In other languages (such as c#), when I assign an object based on a derived class to an object of BaseType: this object starts working with the derived class code. Or If I have a list of BaseType objects and I put derived class based objects in it: every element works according to the specific Type. In c++ no... I obtained this behaiviour in C++ just using pointers. Is there an alternative way? Have i missed something? Here's my code example:



class GenericCar
{

public:

    virtual void PrintModelName()
    {
        std::cout << "No Model Defined \n";
    }

};

class FerrariCar : public GenericCar
{

public:
    void virtual PrintModelName() override
    {
        std::cout<<"Ferrari \n";
    }

};


int main()
{
    std::cout << "Hello World!\n";
    //instance of two Ojects: A generic Car (Base Class) and a Ferrari (inherited class)
    GenericCar Car = GenericCar();
    FerrariCar Ferrari = FerrariCar();

    Car.PrintModelName(); //base method
    Ferrari.PrintModelName(); //overrided method
    ((GenericCar)Ferrari).PrintModelName(); //base method....

    //declaring a List of Generic Cars (Base Class)
    list<GenericCar> ListOfCars; 
    ListOfCars.push_back(Car); //adding BaseClass based Object
    ListOfCars.push_back(Ferrari); //adding InheritedClass based Object
    //for each element i want to print the model name of the Car.
    for (GenericCar & CarElement: ListOfCars)
    {
       //The base method is called for each element. (The second object is Ferrari but the base method is executed)
        CarElement.PrintModelName();
    }

    //Now declaring a List of GenericCar pointers
    list<GenericCar*> ListOfCarsPointers;
    ListOfCarsPointers.push_back(&Car); //adding BaseClass based object address
    ListOfCarsPointers.push_back(&Ferrari);//adding InheritedClass based object address
    //for each element i want to print the model name of the Car.
    for (GenericCar* & CarElement : ListOfCarsPointers)
    {
        //The correct method is invoked. For the object "Ferrari" is called the overrided function instead of base class code)
        CarElement->PrintModelName();
    }

    //Now i try to assign Ferrari to Car (inherited to base)
    Car = Ferrari;//assignment
    Car.PrintModelName();//method invoke. Here, the base method is invoked. Not the overridden code...

    char c;
    std::cin >> c;

}

例如,在C#中,尽管显式转换为基类,但仍会调用覆盖的方法:(BaseClass)InherithedClassObject.method()调用覆盖的方法,而不是基类. 在列表的迭代中:替代方法也被忽略(始终为C#).

In C#, for example, the overridden method is called despite the explicit cast to the base class: (BaseClass)InherithedClassObject.method() invokes the overridden method and not the base one. In the iteration of the list: the overridden method is ivoked, too (Always C#).

在c ++中,我是否总是使用指针来确保发生多态行为的可能性?结果是:我是否要明确地始终管理总是破坏内存分配的对象?

In c++ Have I to use always pointer in order to ensure the possibility of having a polymorphic behavior? As a consequence: Have I to manage always memory allocation destroyng objects explicitally?

推荐答案

将法拉利(Ferrari)列入您的第一个列表时,您会遇到

When you placed Ferrari in your first list you experienced type erasure - the "GenericCar" structure was copied into the list and anything that could have identified that it was a "FerrariCar" was lost.

您需要一个指针或引用来调用多态函数,有一个指针或引用使您可以访问

You need a pointer or reference to invoke polymorphic functions, have a pointer or reference gives you access to the virtual table for your object.

要拥有一个可以存储此类汽车对象并传递给不同功能的列表,您可能需要使用智能指针,以免出现悬空指针或内存泄漏的情况.

To have a list that could store store such car objects and be passed around to different functions you will probably want to use smart pointers so that you don't wind up with dangling pointers or memory leaks.

#include <memory>

...

list<shared_ptr<GenericCar>> cars;
cars.push_back(shared_ptr<GenericCar>(new GenericCar()));
cars.push_back(shared_ptr<GenericCar>(new FerrariCar()));
for ( shared_ptr<GenericCar> & car : cars )
    car->PrintModelName();

这篇关于多态性:在没有指针的情况下调用覆盖的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆