C++ C+中的虚拟方法重写+;
假设我们有一个名为C++ C+中的虚拟方法重写+;,c++,polymorphism,virtual-functions,dynamic-dispatch,C++,Polymorphism,Virtual Functions,Dynamic Dispatch,假设我们有一个名为Vehicle的抽象类: class Vehicle { virtual bool raceWith(Vehicle *anotherVehicle) = 0; }; 我们有它的子类:Bicycle和Car: // forward declaration class Car; class Bicycle : public Vehicle { virtual bool raceWith(Vehicle *anotherVehicle) { t
Vehicle
的抽象类:
class Vehicle {
virtual bool raceWith(Vehicle *anotherVehicle) = 0;
};
我们有它的子类:Bicycle
和Car
:
// forward declaration
class Car;
class Bicycle : public Vehicle {
virtual bool raceWith(Vehicle *anotherVehicle) {
throw SomeExceptionClass();
}
virtual bool raceWith(Car *anotherVehicle) {
return true;
}
virtual bool raceWith(Bicycle *anotherVehicle) {
return false;
}
};
但是,这段代码抛出了一些ExceptionClass:
Vehicle *aBicycle = new Bicycle();
Vehicle *aCar = new Car();
aBicycle->raceWith(aCar);
在这里做什么?C++不允许我们以这种方式使用多态方法吗?< /P>
任何帮助都将不胜感激。谢谢
编辑:用动态播放
和decltype
变体提供答案也很好
Vehicle *aBicycle = new Bicycle();
aBicycle->raceWith(aCar);
aCar的类型是Vehicle(typeid(aCar).name()
),因此编译器正在使用Vehicle调用该方法
试一试
aBicycle->raceWith(静态施法(aCar));
aBicycle->raceWith(动态施法(aCar));
至于为什么
static\u cast
或dynamic\u cast
,你可以看看这篇文章:下面的文章将自行车
与车辆
比赛:
class Vehicle {
virtual bool raceWith(Vehicle *anotherVehicle) = 0;
};
要让自行车
与汽车
比赛,我们需要使用双重调度
为了进行双重调度,我们使用这个指针调用下一个函数,以便第二个虚拟调用可以解析为正确的车辆类型:
class Car;
class Bicycle;
class Vehicle {
public:
virtual bool raceWith(Vehicle& anotherVehicle) = 0;
virtual bool raceWith(Bicycle& anotherVehicle) = 0;
virtual bool raceWith(Car& anotherVehicle) = 0;
};
class Bicycle : public Vehicle {
public:
virtual bool raceWith(Vehicle& anotherVehicle) override
{
//throw std::exception();
return anotherVehicle.raceWith(*this);
}
virtual bool raceWith(Car& anotherVehicle)
{
return true;
}
virtual bool raceWith(Bicycle& anotherVehicle)
{
return false;
}
};
class Car : public Vehicle {
public:
virtual bool raceWith(Vehicle& anotherVehicle) override
{
return true;
}
virtual bool raceWith(Car& anotherVehicle) override
{
return true;
}
virtual bool raceWith(Bicycle& anotherVehicle) override
{
return false;
}
};
int main()
{
Vehicle *aBicycle = new Bicycle();
Vehicle *aCar = new Car();
aBicycle->raceWith(*aCar);
}
注意返回另一辆车。与(*本车)比赛代码>将执行第二个虚拟调用
然后按以下顺序调用函数:
main()代码>
自行车::与(车辆和其他车辆)比赛代码>
Car::与(自行车和其他车辆)比赛代码>
以下是相同的程序,但坚持使用问题中提供的指针和异常:
#include <exception>
class Car;
class Bicycle;
class Vehicle {
public:
virtual bool raceWith(Vehicle* anotherVehicle) = 0;
virtual bool raceWith(Bicycle* bicycle) = 0;
virtual bool raceWith(Car* car) = 0;
};
class Bicycle : public Vehicle {
public:
virtual bool raceWith(Vehicle* anotherVehicle) override
{
//throw std::exception();
return anotherVehicle->raceWith(this);
}
virtual bool raceWith(Car* car) override
{
return true;
}
virtual bool raceWith(Bicycle* bicycle) override
{
return false;
}
};
class Car : public Vehicle {
public:
virtual bool raceWith(Vehicle* anotherVehicle) override
{
throw std::exception();
}
virtual bool raceWith(Car* car) override
{
return true;
}
virtual bool raceWith(Bicycle* bicycle) override
{
return false;
}
};
int main()
{
Vehicle *aBicycle = new Bicycle();
Vehicle *aCar = new Car();
aBicycle->raceWith(aCar);
}
#包括
高级轿车;
高级自行车;
等级车辆{
公众:
虚拟赛车(车辆*其他车辆)=0;
虚拟赛车(自行车*自行车)=0;
虚拟赛车(车*车)=0;
};
自行车类别:公共车辆{
公众:
虚拟赛车(车辆*其他车辆)超越
{
//抛出std::exception();
返回另一辆车->与(本车)比赛;
}
带(车*车)覆盖的虚拟布尔赛车
{
返回true;
}
虚拟布尔赛车(自行车*自行车)覆盖
{
返回false;
}
};
车辆类别:公共车辆{
公众:
虚拟赛车(车辆*其他车辆)超越
{
抛出std::exception();
}
带(车*车)覆盖的虚拟布尔赛车
{
返回true;
}
虚拟布尔赛车(自行车*自行车)覆盖
{
返回false;
}
};
int main()
{
车辆*aBicycle=新自行车();
车辆*aCar=新车();
Abirycle->raceWith(aCar);
}
试试这个,您可以使用动态转换来检测子类的类型。如果将虚拟布尔赛车(车辆*另一辆车)
作为一种方法,则可能虚拟布尔赛车(车辆*另一辆车)
和虚拟布尔赛车(自行车*另一辆车)
将永远不会执行,因为另一辆车
是车辆类型obj。希望会有所帮助:)
#包括
使用名称空间std;
高级轿车;
高级自行车;
等级车辆{
公众:
//虚拟赛车(车辆*其他车辆)=0;
虚拟赛车(车*另一辆车)=0;
虚拟赛车(自行车*其他车辆)=0;
};
自行车类别:公共车辆{
/*虚拟赛车(车辆*其他车辆){
抛出SomeExceptionClass();
}*/
虚拟赛车(车*另一辆车){
很抱歉,我错过了。我说的是subclass。请不要提供这个作为答案。在面向对象编程中,它有一个定义。不幸的是,它从来没有不同。@Leviathlon我删除了我答案的这一部分。同样不,我发现这个问题只能通过双动态调度来解决。什么是双调度?@Leviathlon doUBLE虚拟调度是根据两个对象的动态类型调用正确的实现的能力。C++只提供了一个虚拟调度,在这个< /COD>中,这里描述的是所谓的访问者模式,使用单次调度两次来实现双重调度,解决了这样的问题。reat回答。谢谢你们的关注。我认为,对于你们在这里试图实现的目标,谷歌-访问者设计模式-将帮助你们更多
#include <exception>
class Car;
class Bicycle;
class Vehicle {
public:
virtual bool raceWith(Vehicle* anotherVehicle) = 0;
virtual bool raceWith(Bicycle* bicycle) = 0;
virtual bool raceWith(Car* car) = 0;
};
class Bicycle : public Vehicle {
public:
virtual bool raceWith(Vehicle* anotherVehicle) override
{
//throw std::exception();
return anotherVehicle->raceWith(this);
}
virtual bool raceWith(Car* car) override
{
return true;
}
virtual bool raceWith(Bicycle* bicycle) override
{
return false;
}
};
class Car : public Vehicle {
public:
virtual bool raceWith(Vehicle* anotherVehicle) override
{
throw std::exception();
}
virtual bool raceWith(Car* car) override
{
return true;
}
virtual bool raceWith(Bicycle* bicycle) override
{
return false;
}
};
int main()
{
Vehicle *aBicycle = new Bicycle();
Vehicle *aCar = new Car();
aBicycle->raceWith(aCar);
}
#include <iostream>
using namespace std;
class Car;
class Bicycle;
class Vehicle {
public:
//virtual bool raceWith(Vehicle *anotherVehicle) = 0;
virtual bool raceWith(Car *anotherVehicle) = 0;
virtual bool raceWith(Bicycle *anotherVehicle) = 0;
};
class Bicycle : public Vehicle {
/*virtual bool raceWith(Vehicle *anotherVehicle) {
throw SomeExceptionClass();
}*/
virtual bool raceWith(Car *anotherVehicle) {
cout << "will print" << endl;
return true;
}
virtual bool raceWith(Bicycle *anotherVehicle) {
return false;
}
};
class Car : public Vehicle {
/*virtual bool raceWith(Vehicle *anotherVehicle) {
throw SomeExceptionClass();
}*/
virtual bool raceWith(Car *anotherVehicle) {
return true;
}
virtual bool raceWith(Bicycle *anotherVehicle) {
return false;
}
};
int main()
{
Vehicle *aBicycle = new Bicycle();
Vehicle *aCar = new Car();
if (dynamic_cast<Bicycle*>(aCar) != NULL) {
std::cout << "Race with A Bicycle" << std::endl;
aBicycle->raceWith(static_cast<Bicycle*>(aCar));
}
else if (dynamic_cast<Car*>(aCar) != NULL) {
std::cout << "Race with A Car" << std::endl;
aBicycle->raceWith(static_cast<Car*>(aCar));
}
else {
//throw SomeExceptionClass();
}
//aBicycle->raceWith(aCar);
return 0;
}