我面临以下问题。
我实现父类 - 车辆,它有一些派生类,其中一个 - FastVehicle 。
在程序中我需要存储一个Vector of Vehicle *指针。指针也可以指向Vehicle对象或FastVehicle对象。
1)我希望能够为向量中的每个对象调用方法 print()。 问题是,在FastVehicle的情况下,我也想将参数传递给函数, 我需要调用带签名的函数:
void print(int a)
我对虚函数机制有一点了解,但根据我的知识,它只有在两个函数具有相同的签名时才有效。
我想听听有关如何解决问题的建议。
2)此外,在派生类 FastVehicle 中有一些独特的功能,它不与父类Vehicle共享。 它执行的任务只应对 FastVehicle 对象执行。 实现这一目标的最简洁方法是什么? 我想也许可以实现"空"父类车辆中的虚函数并实现" real"在 FastVehicle
的重写方法中的任务也许有人可以提出更好的解决方案。
感谢
答案 0 :(得分:1)
您始终可以使用dynamic_cast将Vehicle转换为FastVehicle。如果Vehicle不是FastVehicle,则返回NULL。如果你真的应该这样做,这取决于你的使用情况。
for(Vehicle* vehicle : vehicleVector)
{
FastVehicle* fastVehicle = dynamic_cast<FastVehicle*>(vehicle);
if(fastVehicle)
{
fastVehicle->print(1337);
fastVehicle->somethingElse();
}
else
{
vehicle->print();
}
}
此处提供完整示例:https://ideone.com/69n6Jb
答案 1 :(得分:1)
务实的解决方案是:
将int a
参数传递给虚拟print
方法,但在Vehicle
中将其忽略,仅在FastVehicle
如你所知,只需添加一个&#34;空&#34; Vehicle
中无操作的基类的虚函数,仅在FastVehicle
实现
E.g:
struct Vehicle {
virtual ~Vehicle(){}
virtual void print(int /*a*/) const { std::cout << "Vehicle print\n"; }
virtual void somethingElse() { /* no-op */ }
};
struct FastVehicle : Vehicle {
void print(int a) const override {std::cout << "FastVehicle print " << a << "\n";}
void somethingElse() override { std::cout << "Something else!\n"; }
};
for (auto vehicle : vehicles) {
vehicle->print(512);
vehicle->somethingElse();
}
答案 2 :(得分:1)
您很可能需要重新考虑为什么需要FastVehicle的参数,而不是其他任何类型的Vehicle。对我而言,这表明设计糟糕。
只需在基类中声明print(int),覆盖它,但在不需要int的类中,只需忽略它。
答案 3 :(得分:0)
也许你可以用抽象的vehicleI
重构:
struct vehicleI {
....
virtual void print(int) = 0;
}
然后是您的vehicle
:
struct vehicle : vehicleI {
....
void print(int i = 0);
}
和您的fastVehicle
:
struct fastvehicle: vehicleI {
....
void print(int);
}
答案 4 :(得分:0)
如果要正确使用对Vehicle界面的动态调用,则需要定义公共接口。 如果你需要在FastVehicle的情况下指定一个参数,而不是在FastVehicle的情况下,那就不再是一个接口了。
您有两种解决方案:
默认参数
struct Vehicle
{
virtual void print(int a=0) {};
};
struct FastVehicle : public Vehicle
{
void print(int a=0) override {};
};
现在您可以使用或不使用参数调用它们。
第二个选项:
struct Vehicle
{
virtual void print() {};
};
struct FastVehicle : public Vehicle
{
void print() override {};
void setA(int a) { _a = a; }
_a{};
};
现在您可以通过另一种方法设置'a'变量,但不能在通过Vehicle的界面访问对象时设置。