我对虚函数或方法有疑问。我在stackoverflow link to post上发现了一个非常好的帖子,解释了虚函数为何以及如何工作。我理解虚拟功能现在如何工作,但我仍然不明白为什么你需要它们。如果你查看链接和提供的示例,他会创建一个这样的实例:
A *a1 = new B;
a1->show();
但是如果你想使用B中的函数,你为什么要创建这样的实例呢?为什么不这样做:
B b1 = new B;
b1->show();
当我想使用B引用时,为什么我应该使用A指针?
我希望你们明白我不会得到什么,并且可以向我解释。
答案 0 :(得分:2)
扩展代码库以包含从C
派生的类A
。
现在添加一个函数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*
会在调用A*
之前自动转换为display_A
。无论aPtr->show()
指向display_A
还是aPtr
,B
中的C
都有效。这是创建virtual
函数的真正动机。
使用目的
A *a1 = new B;
a1->show();
表示即使指针的类型为B::show()
,如果指针指向的是A*
对象,也会调用B
。
答案 1 :(得分:2)
这是 Polymorphism 的一个很好的例子。
简而言之,多态性允许两种不同的类型(类)为不同的底层实现提供相同的接口。
不要使用A和B作为示例,而应考虑两个类 Motorcycle 和 Car 。 摩托车和汽车都可以驱动,对吗?你驾驶这两辆车的方式是完全不同的。这两个类都应该提供 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);
答案 2 :(得分:1)
最重要的是,当你调用一个虚函数时,它会执行它能够执行该函数的最多派生形式。
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函数。