假设我们有一个名为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;
}
};
但是,这段代码抛出SomeExceptionClass:
Vehicle *aBicycle = new Bicycle();
Vehicle *aCar = new Car();
aBicycle->raceWith(aCar);
这里做什么? C ++不允许我们以这种方式使用多态方法吗?
任何帮助将不胜感激。感谢。
编辑:提供dynamic_cast<>
和decltype
变体的答案也很好吗?
答案 0 :(得分:4)
以下内容将使用Bicycle
:
Vehicle
进行竞争
Vehicle *aBicycle = new Bicycle(); Vehicle *aCar = new Car(); aBicycle->raceWith(aCar);
要使Bicycle
与Car
比赛,我们需要使用双重发送。
为了进行双重调度工作,我们使用this
指针调用下一个函数,以便第二个虚拟调用可以解析为正确类型的车辆:
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);
}
请注意将执行第二次虚拟呼叫的return anotherVehicle.raceWith(*this);
。
然后按以下顺序调用函数:
main();
Bicycle::raceWith(Vehicle& anotherVehicle);
Car::raceWith(Bicycle& anotherVehicle);
以下是相同的程序,但坚持使用问题中提供的指针和异常:
#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);
}
答案 1 :(得分:1)
通过
Vehicle *aBicycle = new Bicycle();
aBicycle->raceWith(aCar);
aCar的类型是Vehicle(typeid(aCar).name()
),因此您的编译器正在使用Vehicle调用该方法。
尝试
aBicycle->raceWith(static_cast<Car*>(aCar));
aBicycle->raceWith(dynamic_cast<Car*>(aCar));
至于为什么static_cast
或dynamic_cast
,你可以在SO上查看这篇文章:Regular cast vs. static_cast vs. dynamic_cast
答案 2 :(得分:1)
试试这个,你可以使用动态强制转换来检测子类的类型。如果您将virtual bool raceWith(Vehicle *anotherVehicle)
作为一种方法,那么virtual bool raceWith(Car *anotherVehicle)
和virtual bool raceWith(Bicycle *anotherVehicle)
可能永远不会在没有强制转换的情况下执行,因为anotherVehicle
是一种车型obj。希望会有所帮助:)
#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;
}