gpt4 book ai didi

C++ 专门化派生类中的继承模板

转载 作者:太空狗 更新时间:2023-10-29 23:14:15 26 4
gpt4 key购买 nike

我正在尝试编写一个程序,其中 ServiceWorker 的派生类(例如 Firefighter)可以“对抗”从事件类(火灾、伤害、抢劫)派生的对象。对抗将返回一个 bool 值,表示它是否成功。例如,面对火灾的消防员会成功,但面对抢劫的消防员则不会。 ServiceWorker 将跟踪对抗和成功对抗的次数,并有一个 confront 方法来确定对抗是否成功。

我想使用特征来存储 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;
};
};

编辑

所以我设法搞清楚了。我摆脱了模板,将 confront 设置为 virtual,因此创建 ServiceWorker 的派生类只需要重新定义虚函数并使用 ServiceWorker::confront。我还添加了 confront_success() 和 calc_ratio() 以便更轻松地添加新的 ServiceWorker。我让 Firefighter::confront() 采用继承自 Incident 的 FirefighterIncident。这样,为 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 { };

类定义之外。 confront一旦if 模板方法将起作用语句替换为

if(can_confront<T>::value)

但是,请记住您仍然面临着 confront 的问题总是使用 ServiceWorker::can_confront<T> ,即使您通过 Firefighter 调用它目的。一个简单的解决方法是复制 confront 的定义进入每个派生类。

关于C++ 专门化派生类中的继承模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34571996/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com