虚拟方法 C++
virtual methods C++
我遇到了以下问题。
我实现父 Class - Vehicle,它有一些派生的 classes,其中之一 - FastVehicle.
在程序中,我需要存储 Vehicle* 指针的 Vector。指针也可以指向 Vehicle 对象或 FastVehicle 对象。
1) 我希望能够为向量中的每个对象调用方法 print()。
问题是,在 FastVehicle 的情况下,我还想将一个参数传递给函数,
我需要调用带有签名的函数:
void print(int a)
我对虚函数机制了解一点,但据我所知,只有当两个函数具有相同的签名时它才有效。
我想听听有关如何解决的建议。
2) 此外在派生的 class FastVehicle 中有一些独特的功能,它不与父 class 车辆共享。
它执行的任务应该只对 FastVehicle 对象执行。
实现这一目标的最干净的方法是什么?
我想也许可以在父 class Vehicle 中实现 "empty" 虚函数,并在 的覆盖方法中实现 "real" 任务快车
也许有人可以提出更好的解决方案。
谢谢
您始终可以使用 dynamic_cast 将 Vehicle 转换为 FastVehicle。如果 Vehicle 不是 FastVehicle,它 returns 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
也许你可以用抽象的方式重构vehicleI
:
struct vehicleI {
....
virtual void print(int) = 0;
}
然后是你的 vehicle
:
struct vehicle : vehicleI {
....
void print(int i = 0);
}
你的fastVehicle
是:
struct fastvehicle: vehicleI {
....
void print(int);
}
实用的解决方案是:
将int a
参数传递给虚拟print
方法但在Vehicle
中忽略它,只在FastVehicle
[=18=中使用它]
正如您所建议的,只需将 "empty" 虚函数添加到基 class 中,它在 Vehicle
中是一个空操作,并且仅在 FastVehicle
例如:
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();
}
如果要正确使用对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 的接口访问该对象时则不能。
很可能您必须重新考虑为什么需要 FastVehicle 的参数,而不是任何其他类型的 Vehicle。这对我来说是糟糕设计的标志。
只需在基 class 中声明 print(int),覆盖它,但在不需要 int 的 classes 中,忽略它即可。
我遇到了以下问题。
我实现父 Class - Vehicle,它有一些派生的 classes,其中之一 - FastVehicle.
在程序中,我需要存储 Vehicle* 指针的 Vector。指针也可以指向 Vehicle 对象或 FastVehicle 对象。
1) 我希望能够为向量中的每个对象调用方法 print()。 问题是,在 FastVehicle 的情况下,我还想将一个参数传递给函数, 我需要调用带有签名的函数:
void print(int a)
我对虚函数机制了解一点,但据我所知,只有当两个函数具有相同的签名时它才有效。
我想听听有关如何解决的建议。
2) 此外在派生的 class FastVehicle 中有一些独特的功能,它不与父 class 车辆共享。 它执行的任务应该只对 FastVehicle 对象执行。 实现这一目标的最干净的方法是什么? 我想也许可以在父 class Vehicle 中实现 "empty" 虚函数,并在 的覆盖方法中实现 "real" 任务快车
也许有人可以提出更好的解决方案。
谢谢
您始终可以使用 dynamic_cast 将 Vehicle 转换为 FastVehicle。如果 Vehicle 不是 FastVehicle,它 returns 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
也许你可以用抽象的方式重构vehicleI
:
struct vehicleI {
....
virtual void print(int) = 0;
}
然后是你的 vehicle
:
struct vehicle : vehicleI {
....
void print(int i = 0);
}
你的fastVehicle
是:
struct fastvehicle: vehicleI {
....
void print(int);
}
实用的解决方案是:
将
int a
参数传递给虚拟print
方法但在Vehicle
中忽略它,只在FastVehicle
[=18=中使用它]正如您所建议的,只需将 "empty" 虚函数添加到基 class 中,它在
Vehicle
中是一个空操作,并且仅在FastVehicle
例如:
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();
}
如果要正确使用对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 的接口访问该对象时则不能。
很可能您必须重新考虑为什么需要 FastVehicle 的参数,而不是任何其他类型的 Vehicle。这对我来说是糟糕设计的标志。
只需在基 class 中声明 print(int),覆盖它,但在不需要 int 的 classes 中,忽略它即可。