我正在尝试解决这个问题,但我不知道如何从接口类转换到我的子类。基本上,我试图将Vehicle指针数组和数组元素作为子类指针,然后逐个元素传递给Counter类方法,它将计算总乘客的值,但是我得到编译器错误:
invalid conversion from 'oss:Vehicle*' to 'oss::Bike*' [-fPermissive]
这是我的代码:
Vehicle.h
using namespace std;
namespace oss{
class Vehicle
{
public:
virtual string type() = 0;
virtual unsigned passengers() = 0;
virtual ~Vehicle();
};
class Land_vehicle : public Vehicle{
protected:
string typeOfVehicle;
unsigned numberOfPassengers;
public:
Land_vehicle();
string type();
};
class Bike : public Land_vehicle{
public:
Bike();
unsigned passengers();
};
class Counter{
private:
int totalPassengers;
public:
Counter();
void add(Bike*b);
int total();
};
Vehicle.cpp
using namespace oss;
Vehicle::~Vehicle(){};
Land_vehicle::Land_vehicle(){typeOfVehicle = "Land";}
string Land_vehicle::type(){return typeOfVehicle;}
Bike::Bike(){numberOfPassengers = 1;}
unsigned Bike::passengers(){return numberOfPassengers;}
Counter::Counter(){totalPassengers = 0;}
void Counter::add(Bike b){
cout <<"inside add bike"<<endl;
totalPassengers += b.passengers();
}
int Counter::total(){return totalPassengers;}
Main.cpp
using namespace std;
using namespace oss;
int main()
{
Counter c;
Vehicle* v[] = {new Bike};
size_t sz = sizeof v/sizeof v[0];
for (unsigned i = 0; i < sz; ++i)
c.add(v[i]);
std::cout << "Total: " << c.total() << " passengers!" << std::endl;
for (unsigned i = 0; i < sz; ++i)
delete v[i];
return 0;
}
答案 0 :(得分:1)
根据您的课程,每个Bike
和每Car
Vehicules. THis is why, whenever you need a
车辆, you can use as well a
自行车* or a
车*。
您在作业中使用此功能:
Vehicle* v[] = {new Bike}; // yes a Bike* can be converted to a Vehicle*
然而反向关系并非如此。 Vehicle
不是每个Bike
都必需的。Vehicle*
。这就是您在需要Bike*
时无法使用Vehicle
的原因。要执行相反的操作,您首先必须检查您正在使用的Bike
是否确实是dynamic_cast()
,如果是这样,您可以使用强制转换。
幸运的是,您的类是多态的(由于虚函数)。所以你必须使用 c.add(v[i]); // v[i] is a pointer to a vehicle, but which one
从父(基)指针转换为子(派生)指针。但请注意检查转换是否成功(即已转换的指针不为空)。
当您尝试将车辆添加到柜台时,您会遇到此问题及相关问题:
Counter::add()
事实上,您的c.add(*v[i])
:
add(Vehicle)
取消引用指针。但是重载需要你在编译时告诉它是哪种类型的对象(即没有c.add(dynamic_cast<Bike*>(v[i]);
,如果有一个,你就会遭受对象切片)for (unsigned i = 0; i < sz; ++i) {
if (dynamic_cast<Bike*>(v[i]))
c.add(dynamic_cast<Bike*>(v[i]));
}
现在将这些放在一起,以下是如何修改循环以仅向自行车添加自行车:
void Counter::add(Bike* b){
cout <<"inside add bike"<<endl;
totalPassengers += b->passengers();
}
这假设要将add的签名更改为:
class Counter {
int totalPassengers;
public:
Counter();
void add(Vehicle* b);
int total();
};
这是 live demo
如果你有多态类,那么不能从多态中受益是一个小小的问题:
void Counter::add(Vehicle* b){
totalPassengers += b->passengers();
}
重新设计的功能的实现:
var SleepyBand_TaskName = "DataHandlerTask";
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == SleepyBand_TaskName)
{
task.Value.Unregister(true);
}
}
var builder = new BackgroundTaskBuilder();
var trigger = new TimeTrigger(16, false);
builder.Name = SleepyBand_TaskName;
builder.TaskEntryPoint = "SleepyBand_BackgroundTasks.DataHandlerTask";
builder.SetTrigger(trigger);
builder.Register();
无论您从车辆中获得多少课程,这都将有效!不再需要添加几十个相同功能的类似重载。