使用虚函数创建实例,为什么?
Instance creation with virtual functions, why?
我对虚函数或方法有疑问。我在 Whosebug link to post 上找到了一个非常好的 post 解释虚函数工作的原因和方式。我现在了解虚拟功能是如何工作的,但我仍然不明白为什么你需要它们。如果您查看 link 和提供的示例,他会创建一个这样的实例:
A *a1 = new B;
a1->show();
但是,如果您想使用 B 中的函数,您为什么要创建这样的实例?为什么不这样做:
B b1 = new B;
b1->show();
当我想使用 B 引用时为什么要使用 A 指针?
我希望你们能理解我不明白的地方,并能向我解释一下。
扩展代码库以包含从 A
.
派生的 class 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*
。 display_A
中的 aPtr->show()
无论 aPtr
指向 B
还是 C
都有效。这就是创建 virtual
函数的真正动机。
使用目的
A *a1 = new B;
a1->show();
是为了证明即使指针是A*
类型,如果指针指向的确实是一个B
对象,B::show()
也会被调用。
这是Polymorphism的一个很好的例子。
简而言之,多态性允许两种不同的类型 (类) 提供具有不同底层实现的相同接口。
不以 A 和 B 为例,考虑两个 类 摩托车 和 汽车。 摩托车和汽车都可以驾驶,对吧?您驾驶这两辆车的方式非常不同。 类 都应该提供 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 函数。
我对虚函数或方法有疑问。我在 Whosebug link to post 上找到了一个非常好的 post 解释虚函数工作的原因和方式。我现在了解虚拟功能是如何工作的,但我仍然不明白为什么你需要它们。如果您查看 link 和提供的示例,他会创建一个这样的实例:
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*
。 display_A
中的 aPtr->show()
无论 aPtr
指向 B
还是 C
都有效。这就是创建 virtual
函数的真正动机。
使用目的
A *a1 = new B;
a1->show();
是为了证明即使指针是A*
类型,如果指针指向的确实是一个B
对象,B::show()
也会被调用。
这是Polymorphism的一个很好的例子。
简而言之,多态性允许两种不同的类型 (类) 提供具有不同底层实现的相同接口。
不以 A 和 B 为例,考虑两个 类 摩托车 和 汽车。 摩托车和汽车都可以驾驶,对吧?您驾驶这两辆车的方式非常不同。 类 都应该提供 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 函数。