【发布时间】:2016-04-06 22:26:27
【问题描述】:
我正在尝试编写一个程序,其中 ServiceWorker 的派生类(例如 Firefighter)可以“对抗”派生自类 Incident(火灾、伤害、抢劫)的对象。对抗将返回是否成功的布尔值。例如,面对火灾的消防员会成功,但面对抢劫的消防员不会成功。 ServiceWorker 将跟踪对抗和成功对抗的数量,并有一个对抗方法来确定对抗是否成功。
我想使用特征来存储 ServiceWorker 的每个派生类在其类定义中可以面对的内容。但是,在 ServiceWorker 中,面对方法创建了特征类,但我想将其专门用于其派生类,因此每个派生类只知道它可以面对什么。
class Incident { };
class Fire : Incident { };
class Robbery : Incident { };
class Injury : Incident { };
class ServiceWorker {
public:
ServiceWorker() : ratio(0), num_success(0), num_confronts(0) {
}
template <typename U>
struct can_confront {
static const bool result = false;
};
double successRatio() {
if(ratio)
return ratio;
else
throw;
}
template <typename T>
void confront(T incident) {
if(can_confront<T>::result)
num_success++;
num_confronts++;
ratio = num_success / num_confronts;
}
protected:
double ratio;
unsigned int num_success;
unsigned int num_confronts;
};
class Firefighter : public ServiceWorker {
public:
template <>
struct can_confront<Fire> {
static const bool result = true;
};
};
编辑
所以我设法弄明白了。我去掉了模板,把 face 变成了虚拟的,所以制作一个 ServiceWorker 的派生类只需要重新定义虚拟函数并使用 ServiceWorker::confront。我还添加了 faces_success() 和 calc_ratio() 以更轻松地添加新的 ServiceWorker。我让 Firefighter::confront() 采用 FirefighterIncident,它继承自 Incident。这样,为 Firefighter 添加新事件会很容易,因为它们只需要从 FirefigerIncident 继承即可。
class Incident {};
class FirefighterIncident : public Incident {};
class Fire : public FirefighterIncident {};
class RescueCat : public FirefighterIncident {};
class ServiceWorker {
public:
ServiceWorker() : ratio(0), num_success(0), num_confronts(0) {
}
double successRatio() {
if(num_confronts != 0)
return ratio;
else {
std::cout << "Can't divide by zero in ratio!" << std::endl;
throw;
}
}
virtual void confront(const Incident&) {
num_confronts++;
calc_ratio();
}
protected:
double ratio;
unsigned int num_success;
unsigned int num_confronts;
void calc_ratio() {
ratio = num_success / (double) num_confronts;
}
void confront_success() {
num_success++;
num_confronts++;
calc_ratio();
}
};
class Firefighter : public ServiceWorker {
public:
using ServiceWorker::confront;
virtual bool confront(const FirefighterIncident&) { confront_success(); }
};
【问题讨论】:
-
不,您不能这样做,您可以在派生类中更改的唯一内容是虚函数实现及其返回类型(协变)。由于
confront不是虚拟的,所以我不知道派生类的存在。 -
您需要双重调度才能拥有
void confront(ServiceWorker&, const Incident&)。 -
@Jarod42 " to have double dispatch" 如果需要运行时多态性,即。
标签: c++ templates inheritance template-specialization