为什么虚拟函数优于派生类对象?

问题描述 投票:0回答:1

因此,我刚开始学习虚函数,并且正在关注在线教程,但似乎找不到我的问题的答案。我想问一个问题,为什么在下面通过将基类对象设置为指向派生类对象来使用虚函数,而不是仅使用派生类对象本身来访问函数呢?

似乎无论哪种方式我都得到相同的输出,并且似乎创建基类对象和虚函数是额外的步骤。我在在线教程中看到了与此类似的示例,该示例声称虚拟函数使编码更容易,但我不太明白此示例的好处吗?

我在线阅读:

虚拟函数的主要优点是它们直接支持面向对象的编程。当您将一个函数声明为虚函数时,您要说的是确切执行什么代码取决于调用它的对象的类型。

但是似乎已经使用派生对象了,创建基类对象是不必要的吗?我确信我缺少明显的东西,因此我将非常感谢您的帮助。我展示了下面编写的示例代码,该代码类似于详细介绍虚函数时看到的代码:

#include <iostream>

using namespace std;

//////////////////////////////////////////////////////
//base class
class Shape {

public:
virtual void draw()=0;  //pure virtual function
};

//derived classes
class Square : public Shape {

public:
void draw() {
    cout << "Draw square" << endl;
    }

};

class Circle : public Shape {

public:
void draw() {
    cout << "Draw circle " << endl;
    }

};

//////////////////////////////////////////////////////
int main()
{
Square so;  //create derived class objects
Circle co;

Shape* shape1 = &so;  //setting base class objects as pointers to derived objects
Shape* shape2 = &co;


shape1->draw();  //using base class objects to access derived class
shape2->draw();

so.draw();  //using derived class objects
co.draw();

}
c++ virtual-functions
1个回答
0
投票

使用基类指针类型和虚函数所获得的巨大好处是,您可以拥有一个包含几种不同类型的Shape的单个列表,并且可以在单个函数中将它们全部处理,由于它们的派生类型而有不同的行为。

作为示例,我通过添加包含DrawAllShapes的函数vector<Shapes*>&修改了您的代码。 (请小心使用原始指针。您确实应该在此处使用vector<std::unique_ptr<Shape>>&或类似的名称。

这种模式具有极大的灵活性,它使您可以在基类指针对象的集合上调用相同的函数,但是根据其派生类型,集合中的每个对象都会导致不同的行为。

#include <iostream>
#include <vector>
using namespace std;

//////////////////////////////////////////////////////
//base class
class Shape {

public:
    virtual void draw() = 0;  //pure virtual function
};

//derived classes
class Square : public Shape {

public:
    void draw() {
        cout << "Draw square" << endl;
    }

};

class Circle : public Shape {

public:
    void draw() {
        cout << "Draw circle " << endl;
    }

};

void DrawAllShapes(std::vector<Shape*>& shapes) {
    for (int i = 0; i < shapes.size(); ++i) {
        shapes[i]->draw();
    }
}

//////////////////////////////////////////////////////
int main()
{
    std::vector<Shape*> shapeVec{ new Square, new Circle, new Square, new Square, new Circle };
    DrawAllShapes(shapeVec);

    system("pause");
}
© www.soinside.com 2019 - 2024. All rights reserved.