C++派生类中专门化继承的模板
C++ Specialize Inherited Template in Derived Class
我正在尝试编写一个程序,其中派生的ServiceWorker 类(如消防员(可以"面对"从类事件(火灾,伤害,抢劫(派生的对象。对抗将返回一个布尔值,即它是否成功。例如,面对火灾的消防员会成功,但面对抢劫的消防员不会。ServiceWorker 将跟踪对抗和成功对抗的数量,并有一个对抗方法来确定对抗是否成功。
我想使用特征来存储 ServiceWorker 的每个派生类在其类定义中可能面对的内容。但是,在 ServiceWorker 中,confront 方法创建了 traits 类,但我想将其专用于其派生类,以便每个派生类只知道它可以面对的内容。
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;
};
};
编辑
所以我设法弄清楚了。我摆脱了模板并制作了虚拟,因此创建ServiceWorker 的派生类只需要重新定义虚拟函数并使用 ServiceWorker::confront。我还添加了 confront_success(( 和 calc_ratio((,以便更轻松地添加新的 ServiceWorkers。我让 Firefighter::confront(( 取 FirefighterIncident,它继承自 Incident。这样,为Firefighter添加新事件将很容易,因为他们只需要从FirefigherIncident继承。
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(); }
};
,如果你利用std::true_type
和std::false_type
,事情就会变得更干净。在基类中,
class ServiceWorker {
public:
template <typename U>
struct can_confront: std::false_type { };
...
在派生类中,
class Firefighter: public ServiceWorker {
public:
template<typename U>
struct can_confront: ServiceWorker::template can_confront<U> { };
...
请注意,我在派生类中重新定义了can_confront
(通过继承(,以便我可以专用于它而无需专用ServiceWorker::can_confront
。为此,只需添加
template<>
struct Firefighter::can_confront<Fire>: std::true_type { };
在类定义之外。一旦将if
语句替换为,confront
模板方法将起作用
if(can_confront<T>::value)
但是,请记住,您仍然会遇到confront
总是使用 ServiceWorker::can_confront<T>
的问题,即使您通过 Firefighter
对象调用它。一个简单的解决方法是将confront
的定义复制到每个派生类中。
- 继承函数的重载解析
- 继承期间显示未知行为的子类
- 头文件-继承c++
- 为什么在保护模式下继承升级不起作用
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 混合组合和继承的C++问题
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 是否可以对零模板参数进行模板专门化
- 从类继承时,继承的类是否会通过父类重新定义继承的变量
- C++派生类中专门化继承的模板
- 从专门化的类继承
- 带有继承的c++模板专门化
- 在完全专门化中,为什么继承使前向声明(没有定义)不再足够?
- 通过继承专门化操作符模板
- 继承vs类模板专门化.设计的家伙
- 模板专门化部分、全部等和继承
- 如何专门化具有继承的复杂模板- c++
- 带有继承的部分专门化.我能避免继承吗?
- 专门化模板类时的继承