繁体   English   中英

用虚拟函数创建实例,为什么?

[英]Instance creation with virtual functions, why?

我有一个关于虚函数或方法的问题。 我在stackoverflow 链接上找到了一篇非常不错的文章, 解释虚拟函数的原因和工作原理。 我了解虚拟功能现在如何工作,但我仍然不明白为什么您需要它们。 如果您查看链接和提供的示例,他将创建一个如下示例:

A *a1 = new B;
a1->show();

但是,如果您要使用B中的函数,您为什么还要创建这样的实例? 为什么不这样做:

B b1 = new B;
b1->show();

我想使用B引用时为什么要使用A指针?

我希望你们能理解我对此一无所知,并可以向我解释。

扩展代码库,使其还包括派生自A的类C

现在添加一个函数display_A ,其定义为:

void display_A(A* aPtr)
{
   a->show();
}

您可以将该函数与B实例以及C实例一起使用。

B* bPtr = new B;
C* cPtr = new C;

display_A(bPtr);
display_A(cPtr);

在这里, B*C*在调用display_A之前自动转换为A* 无论aPtr指向B还是Cdisplay_A aPtr->show()都可以工作。 这是创建virtual功能的真正动机。

使用目的

A *a1 = new B;
a1->show();

的目的是证明即使指针为A*类型,即使指针指向的确实是B对象,也将调用B::show()

这是多态性的一个很好的例子。

简而言之,多态性允许两种不同的类型(类)提供具有不同底层实现的相同接口。

不要以A和B为例,而是考虑MotorcycleCar这两个类。 摩托车汽车都可以驾驶 ,对吗? 您驾驶这两辆车的方式完全不同。 这两个类都应提供drive()方法,尽管它们的实现不同。

class Vehicle {
    public:
        virtual void drive() = 0;
}

class Car : public Vehicle {
    public:
        void drive() {
            // Driving to work, however a car does that.
        };
}

class Motorcycle : public Vehicle {
    public:
        void drive() {
            // Driving to work, however a motorcycle does that.
        };
}
Vehicle *car = new Car;
Vehicle *motorcycle = new Motorcycle;

// We can both be driven, so we share the same interface.
car->drive();
motorcycle->drive();

将对象传递给函数时,这尤其有用。 您具有一项可以发挥作用的功能。 只要您以某种方式被驱动,您就真的不在乎如何工作。

void driveToWork(Vehicle *vehicle) {
    vehicle->drive();
}

driveToWork(new Car);

// It's Tuesday, your car broke down!
// As long as we use a Vehicle to get to work, all is well.
driveToWork(new Motorcycle);

最重要的是,当您调用虚拟函数时,它会执行该函数可以派生的形式最多的形式

class Message
{
     virtual void buildMessage();
}

class ShutdownMessage : public Message
{
     virtual void buildMessage() { /* Do a thing. */ }
}

class StartupMessage : public Message
{
     virtual void buildMessage() { /* Do a totally different thing. */ }
}

void prepareMessage(Message *M)
{
    M->buildMessage();
}

现在您可以调用此命令:

prepareMessage(myMsg);

在任何消息上,它将调用适当的buildMessage函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM